2

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

4 回答 4

5

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

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

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

于 2013-01-16T19:46:42.647 回答
5

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

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

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

struct sockaddr_in6 server, client;
SOCKET sock;
char buffer[BUFFERSIZE];
LPTSTR recvBuff[1024];
于 2013-01-16T19:49:15.543 回答
2

我遇到了同样的错误。

@askMish 的回答非常正确。我一开始并不理解,但最终我发现了。

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

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

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

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

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

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

于 2017-04-18T07:43:42.690 回答
1

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

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

inet_addr()我使用-function生成了我希望服务器在本地绑定的本地地址。我以这种方式将此结果分配给本地地址结构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"); 
}
于 2015-06-09T13:33:33.453 回答