bind()因Windows套接字错误10049而失败

时间:2013-01-16 19:18:09

标签: c windows sockets bind

我尝试使用IPv6和UDP在C中创建客户端/服务器程序。当程序绑定套接字时,它返回WSAError 10049.我知道这是地址名称的问题但是没有看到问题是什么。我希望有人可以提供帮助。

struct sockaddr_in6 server, client;
SOCKET sock;
char buffer[BUFFERSIZE];
LPTSTR recvBuff[1024];
DWORD recvBuffLen = 1024UL;
int len = sizeof(client);

WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(1,1);
WSAStartup(wVersionRequested, &wsaData);

sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (sock < 0)
    error("Fehler beim Anlegen des Sockets");

server.sin6_family = AF_INET6;
server.sin6_port = htons(6000);
server.sin6_addr = in6addr_any;

if (bind(sock, (struct sockaddr *) &server, sizeof(server)) == -1)
    error("Fehler beim binden des Sockets");

4 个答案:

答案 0 :(得分:5)

This normally results from an attempt to bind to an address that is not valid for the local computer.

您应该在此使用PF_INET而不是AF_INET。它们具有相同的值,但您未在此处指定地址系列AF,而是指定协议系列PF。这只是一种风格推荐。

我建议将memset归零以下数组,结构:

struct sockaddr_in6 server, client;
SOCKET sock;
char buffer[BUFFERSIZE];
LPTSTR recvBuff[1024];

答案 1 :(得分:4)

在使用sockaddr_in6结构之前,您必须memset将其设为零:

  memset(server, 0, sizeof(struct sockaddr_in6));

原因是struct sockaddr_in6结构包含您未初始化的其他字段(例如sin6_scope_id),并且可能包含垃圾。

答案 2 :(得分:1)

在Windows下调用bind()时,我有相同的错误代码。

在我的情况下,原因与初始海报的代码不同,但我猜其他人会犯同样的错误:

我使用inet_addr()函数生成了我希望服务器在本地绑定的本地地址。 我以这种方式将此结果分配给本地地址结构struct sockaddr_in localaddr

localaddr.sin_addr.s_addr = htonl(inaddr);

但是inet_addr()已经按字节网络顺序返回地址,因此我的代码中调用htonl(inaddr)错误并导致错误10049:

SOCKET tcpsock_bindlisten(unsigned short port, const char* bindaddr)
{
    SOCKET srvsock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

    unsigned long inaddr = bindaddr ? inet_addr(bindaddr) : INADDR_ANY;

    struct sockaddr_in localaddr;
    memset(&localaddr, 0, sizeof(struct sockaddr_in));
    localaddr.sin_family        = AF_INET;
    localaddr.sin_port          = htons(port);  

    // ERROR HERE! address returned from inet_addr is already in network-byte-order!
    localaddr.sin_addr.s_addr   = htonl(inaddr); 

    // CORRECT THIS WAY:
    localaddr.sin_addr.s_addr   = inaddr;   

    if (bind(srvsock, (struct sockaddr *) &localaddr, sizeof(localaddr)) != 0)
    {
        print_socketerror("tcpsock bind()");
        return INVALID_SOCKET;
    }

    if (listen(srvsock, SVRSOCK_BACKLOG) != 0)
    {
        print_socketerror("tcpsock listen()");
        return INVALID_SOCKET;
    }

    return srvsock;
}

使用“所有本地接口”(bind())调用INADDR_ANY时,由于巧合INADDR_ANY == htonl(INADDR_ANY),所以它有效:

int main()
{
    ...
    // this works for this special case:
    SOCKET svrsock1 = tcpsock_bindlisten(4444, NULL); 

    // did not work!
    SOCKET svrsock2 = tcpsock_bindlisten(5555, "192.168.0.123"); 
}

答案 3 :(得分:1)

我遇到了同样的错误。

@askMish 's answer是对的。我一开始并不理解,但最终我发现它。

  

这通常是因为尝试绑定到对本地计算机无效的地址。

通常我们的计算机位于某个网关之下。

如果我们运行ipconfig,我们会发现IP地址是192.168.something。

这就是我们可以用来绑定代码的IP。

虽然其他人应该与公共IP连接(如果你可以上网,你肯定有一个。)如47.93.something如果他们与你在同一个局域网。

您需要在您的网关(可能是您家人的路线)找到该IP。