You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Windows10+VS2015 C语言Socket服务器绑定/监听异常求助

问题排查:Socket服务器未进入等待客户端连接状态

看了你的代码,问题出在几个关键细节上,导致bindlisten执行失败,程序没走到真正等待客户端连接的accept步骤就直接结束了。我给你逐一拆解并修正:

1. Socket创建的错误判断逻辑错误

Windows下的SOCKET是无符号类型,socket()函数失败时返回的是INVALID_SOCKET(本质是(SOCKET)-1,但直接和-1比较会因为类型不匹配导致判断失效)。你原来的判断方式在Windows环境下完全起不到错误检测作用,应该改成:

if (socket_of_server == INVALID_SOCKET) {
    printf("creating socket failure, error code: %d\n", WSAGetLastError());
    WSACleanup();
    return 1;
}

2. 端口设置的致命错误

你写了address_of_server.sin_port = htons(atoi(10000));,这里atoi要求传入字符串指针,但你传了整数10000,这会被当成一个内存地址去读取,大概率触发非法访问或者得到完全错误的端口值,直接导致bind失败。其实根本不需要用atoi,直接写端口数值即可:

address_of_server.sin_port = htons(10000);

3. 未检查bindlisten的返回值

bind()listen()执行失败时都会返回SOCKET_ERROR,如果这两步失败,后续的accept()也会直接失败,程序会跳过等待逻辑直接走到WSACleanup()然后退出。必须加上错误检查和终止逻辑:

if (bind(socket_of_server, (struct sockaddr*)&address_of_server, sizeof(address_of_server)) == SOCKET_ERROR) {
    printf("bind failure, error code: %d\n", WSAGetLastError());
    closesocket(socket_of_server);
    WSACleanup();
    return 1;
}

if (listen(socket_of_server, 5) == SOCKET_ERROR) {
    printf("listen failure, error code: %d\n", WSAGetLastError());
    closesocket(socket_of_server);
    WSACleanup();
    return 1;
}

4. 补充accept后的基础逻辑(可选但建议)

就算accept成功,你的原程序也会直接退出,建议加上客户端连接提示和简单的消息处理,方便验证:

socket_of_client = accept(socket_of_server, (struct sockaddr*)&address_of_client, &size_of_address_of_client);
if (socket_of_client == INVALID_SOCKET) {
    printf("accept failure, error code: %d\n", WSAGetLastError());
    closesocket(socket_of_server);
    WSACleanup();
    return 1;
}
printf("Client connected from: %s:%d\n", inet_ntoa(address_of_client.sin_addr), ntohs(address_of_client.sin_port));

// 简单接收客户端消息示例
char buffer[1024];
int recv_len = recv(socket_of_client, buffer, sizeof(buffer)-1, 0);
if (recv_len > 0) {
    buffer[recv_len] = '\0';
    printf("Received from client: %s\n", buffer);
}

// 关闭客户端socket
closesocket(socket_of_client);

修正后的完整代码

#include <stdio.h>
#include <winsock2.h>
#include <stdlib.h> // 为了atoi(如果需要的话)

int main(int argc, char *argv[]) {
    WSADATA wsaData;
    struct sockaddr_in address_of_server;
    struct sockaddr_in address_of_client;
    int socket_of_client;
    int size_of_address_of_client = sizeof(address_of_client);

    if (WSAStartup(MAKEWORD(2, 2), &wsaData) == 0) {
        printf("winsock initialization success\n");
    } else {
        printf("winsock initialization failure\n");
        return 1;
    }

    SOCKET socket_of_server = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_of_server == INVALID_SOCKET) {
        printf("creating socket failure, error code: %d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    } else {
        printf("creating socket success\n");
    }

    memset(&address_of_server, 0, sizeof(address_of_server));
    address_of_server.sin_family = AF_INET;
    address_of_server.sin_addr.s_addr = htonl(INADDR_ANY);
    address_of_server.sin_port = htons(10000); // 修正端口设置

    // 检查bind结果
    if (bind(socket_of_server, (struct sockaddr*)&address_of_server, sizeof(address_of_server)) == SOCKET_ERROR) {
        printf("bind failure, error code: %d\n", WSAGetLastError());
        closesocket(socket_of_server);
        WSACleanup();
        return 1;
    }
    printf("bind success\n");

    // 检查listen结果
    if (listen(socket_of_server, 5) == SOCKET_ERROR) {
        printf("listen failure, error code: %d\n", WSAGetLastError());
        closesocket(socket_of_server);
        WSACleanup();
        return 1;
    }
    printf("listen success, waiting for client connection...\n");

    socket_of_client = accept(socket_of_server, (struct sockaddr*)&address_of_client, &size_of_address_of_client);
    if (socket_of_client == INVALID_SOCKET) {
        printf("accept failure, error code: %d\n", WSAGetLastError());
        closesocket(socket_of_server);
        WSACleanup();
        return 1;
    }
    printf("Client connected from: %s:%d\n", inet_ntoa(address_of_client.sin_addr), ntohs(address_of_client.sin_port));

    // 简单接收逻辑
    char buffer[1024];
    int recv_len = recv(socket_of_client, buffer, sizeof(buffer)-1, 0);
    if (recv_len > 0) {
        buffer[recv_len] = '\0';
        printf("Received from client: %s\n", buffer);
    }

    closesocket(socket_of_client);
    closesocket(socket_of_server);
    WSACleanup();
    return 0;
}

编译运行后,你可以用telnet 127.0.0.1 10000或者其他Socket客户端工具连接,就能看到程序进入等待状态并处理连接了。

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

火山引擎 最新活动