win32平台下通过WinSock2用C++实现一个非阻塞模式TCP客户端
时间: 2024-02-13 12:02:09 浏览: 248
c++开发的socket TCP客户端
4星 · 用户满意度95%
好的,以下是一个简单的非阻塞模式TCP客户端的C++代码实现:
首先,我们需要包含WinSock2.h头文件和Windows.h头文件,并链接ws2_32.lib库文件:
```cpp
#include <WinSock2.h>
#include <Windows.h>
#pragma comment(lib, "ws2_32.lib")
```
然后,我们需要初始化WinSock2库:
```cpp
WSADATA wsaData;
int ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (ret != 0) {
printf("WSAStartup failed with error %d\n", ret);
return -1;
}
```
接下来,创建一个socket:
```cpp
SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket == INVALID_SOCKET) {
printf("socket failed with error %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
```
然后,将socket设置为非阻塞模式:
```cpp
u_long iMode = 1;
ret = ioctlsocket(clientSocket, FIONBIO, &iMode);
if (ret != NO_ERROR) {
printf("ioctlsocket failed with error %d\n", ret);
closesocket(clientSocket);
WSACleanup();
return -1;
}
```
接下来,定义服务器的地址和端口号:
```cpp
const char* serverAddr = "127.0.0.1";
const int serverPort = 12345;
```
创建一个sockaddr_in结构体,用于存储服务器的地址和端口号:
```cpp
sockaddr_in serverAddrIn;
serverAddrIn.sin_family = AF_INET;
serverAddrIn.sin_addr.s_addr = inet_addr(serverAddr);
serverAddrIn.sin_port = htons(serverPort);
```
然后,连接服务器:
```cpp
ret = connect(clientSocket, (sockaddr*)&serverAddrIn, sizeof(serverAddrIn));
if (ret == SOCKET_ERROR) {
if (WSAGetLastError() != WSAEWOULDBLOCK) {
printf("connect failed with error %d\n", WSAGetLastError());
closesocket(clientSocket);
WSACleanup();
return -1;
}
}
```
由于是非阻塞模式,所以连接函数可能会返回WSAEWOULDBLOCK错误,这是正常情况。
接下来,我们需要使用select函数来检查连接是否完成:
```cpp
fd_set writeSet;
FD_ZERO(&writeSet);
FD_SET(clientSocket, &writeSet);
timeval timeVal;
timeVal.tv_sec = 5;
timeVal.tv_usec = 0;
ret = select(0, NULL, &writeSet, NULL, &timeVal);
if (ret == SOCKET_ERROR) {
printf("select failed with error %d\n", WSAGetLastError());
closesocket(clientSocket);
WSACleanup();
return -1;
}
else if (ret == 0) {
printf("select timed out\n");
closesocket(clientSocket);
WSACleanup();
return -1;
}
```
如果连接完成,writeSet中的clientSocket将变为可写状态。
最后,我们可以向服务器发送数据:
```cpp
char* sendData = "Hello, server!";
int sendLen = strlen(sendData);
ret = send(clientSocket, sendData, sendLen, 0);
if (ret == SOCKET_ERROR) {
printf("send failed with error %d\n", WSAGetLastError());
closesocket(clientSocket);
WSACleanup();
return -1;
}
```
完整的代码如下:
```cpp
#include <WinSock2.h>
#include <Windows.h>
#pragma comment(lib, "ws2_32.lib")
int main() {
WSADATA wsaData;
int ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (ret != 0) {
printf("WSAStartup failed with error %d\n", ret);
return -1;
}
SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket == INVALID_SOCKET) {
printf("socket failed with error %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
u_long iMode = 1;
ret = ioctlsocket(clientSocket, FIONBIO, &iMode);
if (ret != NO_ERROR) {
printf("ioctlsocket failed with error %d\n", ret);
closesocket(clientSocket);
WSACleanup();
return -1;
}
const char* serverAddr = "127.0.0.1";
const int serverPort = 12345;
sockaddr_in serverAddrIn;
serverAddrIn.sin_family = AF_INET;
serverAddrIn.sin_addr.s_addr = inet_addr(serverAddr);
serverAddrIn.sin_port = htons(serverPort);
ret = connect(clientSocket, (sockaddr*)&serverAddrIn, sizeof(serverAddrIn));
if (ret == SOCKET_ERROR) {
if (WSAGetLastError() != WSAEWOULDBLOCK) {
printf("connect failed with error %d\n", WSAGetLastError());
closesocket(clientSocket);
WSACleanup();
return -1;
}
}
fd_set writeSet;
FD_ZERO(&writeSet);
FD_SET(clientSocket, &writeSet);
timeval timeVal;
timeVal.tv_sec = 5;
timeVal.tv_usec = 0;
ret = select(0, NULL, &writeSet, NULL, &timeVal);
if (ret == SOCKET_ERROR) {
printf("select failed with error %d\n", WSAGetLastError());
closesocket(clientSocket);
WSACleanup();
return -1;
}
else if (ret == 0) {
printf("select timed out\n");
closesocket(clientSocket);
WSACleanup();
return -1;
}
char* sendData = "Hello, server!";
int sendLen = strlen(sendData);
ret = send(clientSocket, sendData, sendLen, 0);
if (ret == SOCKET_ERROR) {
printf("send failed with error %d\n", WSAGetLastError());
closesocket(clientSocket);
WSACleanup();
return -1;
}
closesocket(clientSocket);
WSACleanup();
return 0;
}
```
希望对你有所帮助!
阅读全文