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

Winsock服务器Bind失败错误10047问题求助

Winsock bind()错误10047的排查与解决

问题描述

参照两年前的教程编写Winsock服务器代码,已将sockaddr_in.sin_family设置为AF_INET,但调用bind()时出现错误10047。已尝试执行netsh winsock reset命令并重启电脑、修改hosts文件确认本地回环地址正确,但问题仍未解决。

服务器代码

#pragma once
#include <WinSock2.h>
#include <tchar.h>
#include<WS2tcpip.h>
#include <map>
#include <string>
#include <iostream>

/*
struct sockaddr_in {
    unsigned short sin_port;
    unsigned short sin_family;
    struct in_addr sin_addr;
    char sin_zero[8];
};
*/

class Log {
    int OutputMessageLogLevel = 1; //will output to a .txt log file if its a warning or higher
    int LogLevel = 0; //0 will be generic print

    public:
    void SetLogLevel(int NewLogLevel) {
        LogLevel = NewLogLevel;
    }

    void print(std::string Message) {
        if (LogLevel == 0) {
            std::cout << Message << std::endl;
        }
        else
        {
            if (LogLevel == 1) {
                std::cout << "[Warning] " + Message << std::endl;
            }
            else
            {
                if (LogLevel == 2) {
                    std::cout << "[Error] " + Message << std::endl;
                }
            }
        }
    }
};

int main() {
    Log logger;

    SOCKET ServerSocket, AcceptSocket;
    int port = 55555;
    WSADATA wsaData;

    int wsaerr;
    WORD WindowsVersionRequested = MAKEWORD(2, 2);
    wsaerr = WSAStartup(WindowsVersionRequested, &wsaData);

    if (wsaerr != 0) {
        logger.print("The Winsock dll is not found ):");
        return wsaerr;
    }
    else
    {
        std::string WSAStatus = wsaData.szSystemStatus;
        logger.print("The Winsock dll is found (: ");
        logger.print("Status: " + WSAStatus);
    }

    ServerSocket = INVALID_SOCKET;
    ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (ServerSocket == INVALID_SOCKET) {
        logger.print("Error at socket(): ");
        return 0;
    }
    else
    {
        logger.print("socket() is Good to go");
    }

    logger.print("Now binding server socket...");

    sockaddr_in service; //buffer to store numerical binary representation of the IP address. also see struct sockaddr_in above
    //The IP address is returned in network byte order.

    service.sin_family = AF_INET; //To use IPV4 configuration or whatever
    InetPton(AF_INET, _T("127.0.0.1"), &service); //127.0.0.1 will loop back to your own machine for local testing
    service.sin_port = htons(port); //port is 55555 the integer which we initialize up top
    
    if (bind(ServerSocket, (SOCKADDR*)&service, sizeof(service)) == SOCKET_ERROR) {
        logger.print("bind() failed: ");
        std::cout << WSAGetLastError() << std::endl;
        closesocket(ServerSocket);
        return 0;
    }
    else
    {
        logger.print("bind() is okay,Success binding socket");
    }

    //int listen(SOCKET s, int backlog);

    if (listen(ServerSocket, 1) == SOCKET_ERROR) {
        logger.print("Could not listen for Socket: ");
        return -1;
    }
    else
    {
        logger.print("Could not listen for Socket: ");
    }

    logger.print("Accepting Connections...");

    AcceptSocket = accept(ServerSocket, NULL, NULL);
    if (AcceptSocket == INVALID_SOCKET) {
        logger.print("Accept Failed: ");
        return -1;
    } {
        logger.print("Accepted Connection!");
        system("pause");
        WSACleanup();
    }
    
};

运行输出

The Winsock dll is found (: 
Status: Running
socket() is Good
Now binding server socket...
bind() failed:
10047

错误原因与解决方法

错误原因

错误10047的核心是地址族不匹配:

  • InetPton(AF_INET, ...)的第三个参数应指向in_addr类型变量(即sockaddr_in的sin_addr成员),但你传入了整个sockaddr_in结构体的指针&service,导致IP地址数据覆盖了之前设置的sin_family,使其不再是AF_INET。
  • 代码中注释的sockaddr_in结构体定义错误(sin_port和sin_family顺序写反),这也可能误导了你对结构体的理解。

解决步骤

  1. 修正InetPton调用参数
    将第三个参数改为&service.sin_addr,确保IP地址写入正确位置:

    InetPton(AF_INET, _T("127.0.0.1"), &service.sin_addr);
    
  2. 初始化结构体避免垃圾数据
    在填充sockaddr_in前,用memset将整个结构体初始化为0:

    memset(&service, 0, sizeof(service));
    
  3. 修正结构体注释
    替换错误的注释为正确的sockaddr_in定义:

    struct sockaddr_in {
        short sin_family;       // 地址族,如AF_INET
        u_short sin_port;       // 端口号,网络字节序
        struct in_addr sin_addr;// IP地址
        char sin_zero[8];       // 填充用,使大小与sockaddr一致
    };
    

修改完成后重新编译运行,bind()即可正常执行。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 03:45:06