You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 11:30:08