使用Winsock2开发Windows Socket客户端时遭遇错误10038求助
Winsock2连接错误10038(对非Socket对象执行操作)排查
问题背景
平时在Unix环境开发Socket客户端,转用Windows Winsock2库开发时,连接指定IP出现错误10038。查MSDN得知该错误是对非Socket对象执行Socket操作导致,推测问题出在Socket创建或地址绑定环节,但自查代码未发现问题。
错误根源
代码中Socket创建的判断语句存在运算符优先级问题:
if (cs = socket(AF_INET, SOCK_STREAM, 0) == INVALID_SOCKET)
==的优先级高于=,实际执行逻辑是先判断socket()的返回值是否等于INVALID_SOCKET,再将布尔结果(0或1)赋值给cs。这导致cs根本不是有效的Socket句柄,后续调用connect自然触发错误10038。
修复方案
给赋值语句添加括号,确保先执行socket()调用并赋值给cs,再判断是否为无效Socket:
if ((cs = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
修复后的完整代码
#include <stdio.h> #include <WinSock2.h> #include <ws2tcpip.h> #define okay(msg, ...) printf("[+] " msg "\n", ##__VA_ARGS__) #define info(msg, ...) printf("[!] " msg "\n", ##__VA_ARGS__) #define error(msg, ...) printf("[-] " msg "\n", ##__VA_ARGS__) int main() { WSADATA wsa; SOCKET cs; struct sockaddr_in addr; char* ip = "127.0.0.1"; int port = 4444; info("Initializing socket..."); if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) { error("Couldn't initialize socket. Error -> %d", WSAGetLastError()); WSACleanup(); return EXIT_FAILURE; } okay("Succesfully initialized socket."); info("Creating socket..."); // 修复运算符优先级问题:给赋值语句添加括号 if ((cs = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { error("Couldn't create socket. Error -> %d", WSAGetLastError()); WSACleanup(); return EXIT_FAILURE; } okay("Succesfully created socket."); addr.sin_family = AF_INET; InetPton(AF_INET, ip, &addr.sin_addr.s_addr); addr.sin_port = htons(port); info("Connecting to -> %s:%d", ip, port); if (connect(cs, (SOCKADDR *) &addr, sizeof(addr)) != 0) { error("Couldn't connect to %s:%d, error -> %d", ip, port, WSAGetLastError()); closesocket(cs); // 新增:连接失败时关闭已创建的Socket WSACleanup(); return EXIT_FAILURE; } okay("Connected to %s:%d", ip, port); char* msg = "lol"; int response = send(cs, msg, strlen(msg), 0); if(response == SOCKET_ERROR){ error("Couldn't send message to %s:%d", ip, port); info("Closing socket..."); closesocket(cs); WSACleanup(); okay("Succesfully closed socket."); return EXIT_FAILURE; } okay("Succesfully sent %d bytes to %s:%d", response, ip, port); info("Closing socket..."); closesocket(cs); // 新增:正常结束时关闭Socket句柄 WSACleanup(); okay("Succesfully closed socket."); return EXIT_SUCCESS; }
额外优化点
- 补充
closesocket(cs)调用:无论连接成功或失败,都需要先关闭创建的Socket句柄,再调用WSACleanup,避免资源泄漏。 - 修正宏定义中的换行符:将原宏里的直接换行改为
\n,避免编译警告。
内容的提问来源于stack exchange,提问作者AleDev
相关产品推荐
相关产品推荐

