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

Windows7下C语言编写的TCP客户端遇Socket error 10054(Connection reset by peer)及服务器netstat无监听端口问题求助

问题分析与解决建议

让我帮你拆解一下问题的根源,你的服务器和客户端代码里存在几个关键错误,直接导致了当前的现象:

1. 服务器端accept语句的运算符优先级错误(核心问题)

看服务器代码里的这一行:

if (client_socket = accept(server_socket, NULL, NULL) == INVALID_SOCKET)

C语言中==的优先级高于=,所以这行代码的实际执行逻辑是:

  1. 先判断accept(server_socket, NULL, NULL)的返回值是否等于INVALID_SOCKET
  2. 把这个判断的布尔结果(0或1)赋值给client_socket

这就导致client_socket拿到的根本不是有效的客户端套接字,而是一个无效的数值。后续的send操作其实是在一个无效套接字上执行的(虽然你的服务器代码没检查send的返回值,所以误以为发送成功),而且服务器在执行完这些操作后直接关闭了监听套接字并退出,客户端的连接因此被重置,触发了10054错误。

修复方法:给赋值表达式加上括号,确保先执行赋值再判断:

if ((client_socket = accept(server_socket, NULL, NULL)) == INVALID_SOCKET)

2. 服务器端send函数的参数错误

你的服务器代码中发送消息的语句:

send(client_socket, server_message, sizeof(server_message), 0);

sizeof(server_message)获取的是指针的大小(32位系统是4字节,64位是8字节),而不是字符串的实际长度。这会导致只发送了字符串的前几个字符,甚至可能发送不完整。

修复方法:使用strlen获取字符串长度,加上1以包含字符串终止符\0:

char *server_message = "You have reached the server!";
int send_len = strlen(server_message) + 1;
if (send(client_socket, server_message, send_len, 0) == SOCKET_ERROR) {
    printf("Send failed: %d\n", WSAGetLastError());
}

同时建议加上send的返回值检查,避免出现隐性错误。

3. 服务器生命周期问题(导致netstat看不到监听)

当前服务器处理完一个连接(哪怕是错误的连接)后,直接关闭监听套接字并退出程序。当你运行netstat命令时,服务器已经停止运行了,自然看不到9002端口的监听状态。

修复方法:把连接处理逻辑放到循环中,让服务器持续监听新连接,并且只关闭客户端套接字,保留监听套接字:

// 在listen之后添加循环
while (1) {
    puts("Waiting for incoming connections...");
    SOCKET client_socket = accept(server_socket, NULL, NULL);
    if (client_socket == INVALID_SOCKET) {
        printf("Error accepting connections: %d\n", WSAGetLastError());
        continue;
    }
    puts("Connection accepted!");

    // 发送消息
    char *server_message = "You have reached the server!";
    int send_len = strlen(server_message) + 1;
    if (send(client_socket, server_message, send_len, 0) == SOCKET_ERROR) {
        printf("Send failed: %d\n", WSAGetLastError());
    } else {
        puts("Message sent!");
    }

    // 关闭客户端套接字,而非监听套接字
    closesocket(client_socket);
}

// 只有当程序退出循环时才关闭监听套接字
closesocket(server_socket);

这样服务器会一直处于监听状态,此时运行netstat -ano | findstr :9002就能看到9002端口处于LISTENING状态了。

4. 客户端代码的优化建议

  • 客户端的recv操作没有处理字符串终止符,可能导致输出乱码,建议添加终止符:
    char buffer[256];
    int recv_len = recv(network_socket, buffer, sizeof(buffer) - 1, 0);
    if (recv_len == SOCKET_ERROR) {
        printf("Receive error: %d\n", WSAGetLastError());
        WSACleanup();
        return EXIT_FAILURE;
    }
    buffer[recv_len] = '\0'; // 添加字符串终止符
    printf("The server sent the data: %s\n", buffer);
    
  • 代码中同时使用了inet_addr和inet_pton设置服务器地址,属于冗余操作,建议保留更安全的inet_pton即可,删除server_address.sin_addr.s_addr = inet_addr("127.0.0.1");这一行。

验证步骤

  1. 修复服务器代码的上述错误后重新编译运行
  2. 当服务器显示Waiting for incoming connections...时,打开命令提示符运行netstat -ano | findstr :9002,确认端口处于监听状态
  3. 运行客户端程序,此时应该能正常接收服务器发送的消息,不再出现10054错误

内容的提问来源于stack exchange,提问作者Leonardo Araujo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 17:22:44