下面是一个在Windows环境下使用C语言编写的非阻塞式TCP连接的客户端示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#define DEFAULT_PORT "8080"
#define SERVER_IP "127.0.0.1"
int main() {
WSADATA wsaData;
SOCKET clientSocket = INVALID_SOCKET;
struct addrinfo* result = NULL, * ptr = NULL, hints;
// 初始化Winsock库
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("Failed to initialize winsock\n");
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC; // 支持IPv4和IPv6
hints.ai_socktype = SOCK_STREAM; // TCP流式套接字
hints.ai_protocol = IPPROTO_TCP; // 使用TCP协议
// 解析服务器地址信息
if (getaddrinfo(SERVER_IP, DEFAULT_PORT, &hints, &result) != 0) {
printf("Failed to resolve server address\n");
WSACleanup();
return 1;
}
// 创建套接字并进行非阻塞设置
clientSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
// 设置为非阻塞模式
u_long mode = 1;
if (ioctlsocket(clientSocket, FIONBIO, &mode) != NO_ERROR) {
printf("Failed to set socket as non-blocking\n");
freeaddrinfo(result);
closesocket(clientSocket);
WSACleanup();
return 1;
}
// 连接服务器
if (connect(clientSocket, result->ai_addr, (int)result->ai_addrlen) == SOCKET_ERROR) {
int errorCode = WSAGetLastError();
if (errorCode != WSAEWOULDBLOCK && errorCode != WSAEINPROGRESS) {
printf("Failed to connect to server\n");
freeaddrinfo(result);
closesocket(clientSocket);
WSACleanup();
return 1;
}
}
// 等待连接完成(非阻塞)
fd_set writeSet;
FD_ZERO(&writeSet);
FD_SET(clientSocket, &writeSet);
struct timeval timeout;
timeout.tv_sec = 5; // 设置超时时间为5秒
timeout.tv_usec = 0;
if (select(0, NULL, &writeSet, NULL, &timeout) <= 0) {
printf("Connection timed out or failed\n");
freeaddrinfo(result);
closesocket(clientSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
printf("Connected to the server!\n");
// 发送消息给服务器
const char* message = "hello";
if (send(clientSocket, message, strlen(message), 0) == SOCKET_ERROR)
{
printf("Failed to send message\n");
closesocket(clientSocket);
WSACleanup();
return 1;
}
printf("Message sent: %s\n", message);
closesocket(clientSocket);
WSACleanup();
return 0;
}
请注意,在使用此代码之前,您需要安装并链接Winsock库。编译时,请确保将-lws2_32
选项添加到编译命令中。
该代码通过使用ioctlsocket()
函数将套接字设置为非阻塞模式,并使用select()
函数等待连接完成。然后,它发送”hello”消息给服务器。
内容由零声教学AI助手提供,问题来源于学员提问