使用C++写一个异步的TCP客户端
时间: 2024-04-29 07:24:22 浏览: 158
由于异步编程需要使用操作系统提供的异步IO接口,因此需要使用操作系统相关的库函数。下面给出一个使用Windows Socket编写的异步TCP客户端的示例代码:
```c
#include <stdio.h>
#include <winsock2.h>
#include <windows.h>
#define BUF_SIZE 1024
void error_handling(const char* msg);
int main(int argc, char* argv[])
{
WSADATA wsaData;
SOCKET sock;
SOCKADDR_IN serv_addr;
HANDLE hIocp;
OVERLAPPED overlapped;
DWORD bytesTransferred;
DWORD flags = 0;
char buf[BUF_SIZE];
int str_len, addr_size;
if (argc != 3) {
printf("Usage: %s <IP> <port>\n", argv[0]);
return 1;
}
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
error_handling("WSAStartup() error");
}
sock = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
if (sock == INVALID_SOCKET) {
error_handling("WSASocket() error");
}
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
serv_addr.sin_port = htons(atoi(argv[2]));
if (connect(sock, (SOCKADDR*)&serv_addr, sizeof(serv_addr)) == SOCKET_ERROR) {
if (WSAGetLastError() != WSAEWOULDBLOCK) {
error_handling("connect() error");
}
}
hIocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
if (hIocp == NULL) {
error_handling("CreateIoCompletionPort() error");
}
if (CreateIoCompletionPort((HANDLE)sock, hIocp, (DWORD)sock, 0) == NULL) {
error_handling("CreateIoCompletionPort() error");
}
memset(&overlapped, 0, sizeof(overlapped));
overlapped.hEvent = WSACreateEvent();
if (overlapped.hEvent == NULL) {
error_handling("WSACreateEvent() error");
}
while (1) {
str_len = scanf("%s", buf);
if (str_len == EOF) {
break;
}
WSASend(sock, buf, str_len, &bytesTransferred, 0, &overlapped, NULL);
memset(&overlapped, 0, sizeof(overlapped));
overlapped.hEvent = WSACreateEvent();
if (overlapped.hEvent == NULL) {
error_handling("WSACreateEvent() error");
}
if (WSARecv(sock, buf, BUF_SIZE, &bytesTransferred, &flags, &overlapped, NULL) == SOCKET_ERROR) {
if (WSAGetLastError() != WSA_IO_PENDING) {
error_handling("WSARecv() error");
}
}
if (WaitForSingleObject(overlapped.hEvent, INFINITE) == WAIT_FAILED) {
error_handling("WaitForSingleObject() error");
}
if (WSAGetOverlappedResult(sock, &overlapped, &bytesTransferred, FALSE, &flags) == FALSE) {
error_handling("WSAGetOverlappedResult() error");
}
buf[bytesTransferred] = '\0';
printf("Received message: %s\n", buf);
}
closesocket(sock);
WSACleanup();
return 0;
}
void error_handling(const char* msg)
{
fprintf(stderr, "%s\n", msg);
exit(1);
}
```
该程序使用了Windows Socket的异步IO接口,通过CreateIoCompletionPort函数创建了一个IOCP对象,然后将客户端套接字关联到该IOCP对象上。在发送消息时,使用WSASend函数发送数据,然后在接收消息时,使用WSARecv函数进行异步接收,然后等待接收完成的事件被触发,再使用WSAGetOverlappedResult函数获取接收到的数据。由于使用了异步IO接口,因此程序能够在数据发送和接收时继续执行其他操作,从而实现了异步功能。
阅读全文