C语言 bind() 失败,Windows 套接字错误 10049

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14366048/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:03:43  来源:igfitidea点击:

bind() fails with windows socket error 10049

cwindowssocketsbind

提问by Markus Wilhelm

I try to make a client/server program in C with IPv6 and UDP. When the program binds the socket it return the WSAError 10049. I know that this is a problem with the adress name but don't see whats the problem. I hope someone can help.

我尝试使用 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");

回答by Bart Friederichs

Before you can use the sockaddr_in6struct, you will have to memsetit to zero:

在您可以使用该sockaddr_in6结构之前,您必须将memset其归零:

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

The reason is that the struct sockaddr_in6structure contains other fields which you are not initializing (such as sin6_scope_id) and which might contain garbage.

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

回答by askmish

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

这通常是由于尝试绑定到对本地计算机无效的地址造成的。.

You should use PF_INEThere instead of AF_INET. They have the same value, but you're not specifying an address family AFhere, you're specifying a protocol family PF. This is just a style recommendation.

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

I would suggest to memsetzero the below arrays,structures:

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

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

回答by CaptainDouche

I had that same error code when calling bind()under windows.

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

The reason in my case was not the same as in the initial poster's code, but i guess other will have made the very same mistake as me:

在我的案例中的原因与最初海报代码中的原因不同,但我想其他人会犯和我一样的错误:

I generated the local address on which i want the server to be bound locally using the inet_addr()-function. I assigned this result to the local address structure struct sockaddr_in localaddrthis way:

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

localaddr.sin_addr.s_addr = htonl(inaddr);

localaddr.sin_addr.s_addr = htonl(inaddr);

But inet_addr()already returns the address in byte-network-order, so the call htonl(inaddr)was wrong in my code and caused error 10049:

但是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;
}

When calling bind()using "all local interfaces" (INADDR_ANY) it worked, because of this coincidence INADDR_ANY == htonl(INADDR_ANY):

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"); 
}

回答by Shihe Zhang

I have faced the same error.

我遇到了同样的错误。

@askMish 's answeris quite right.I didn't understand it at the first place,however I find it out eventually.

@askMish 的回答非常正确。我一开始不明白,但我最终找到了它。

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

这通常是由于尝试绑定到对本地计算机无效的地址造成的。

Normally we have our computer under some gateway.

通常我们在某个网关下有我们的计算机。

If we run ipconfigwe will find the IP address is 192.168.something.

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

So that's the IP we could use to bind in code.

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

While other should connect with the public IP(if you can surf Internet you have one for sure.) like 47.93.something if they are in the same LAN with you.

而其他应该连接到公共 IP(如果你可以上网,你肯定有一个。)比如 47.93.something 如果他们和你在同一个局域网中。

You need to find that IP at your gateway(possibly your family's route).

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