我尝试使用IPv6和UDP在C中创build客户端/服务器程序。 当程序绑定套接字时,它将返回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");
这通常是由于尝试绑定到对本地计算机无效的地址所致。 。
你应该在这里使用PF_INET
而不是AF_INET
。 它们具有相同的值,但是您并没有在这里指定地址族AF
,而是指定了一个协议族PF
。 这只是一个风格建议。
我会建议memset
零下面的数组,结构:
struct sockaddr_in6 server, client; SOCKET sock; char buffer[BUFFERSIZE]; LPTSTR recvBuff[1024];
在你使用sockaddr_in6
结构体之前,你必须将它设置为零:
memset(server, 0, sizeof(struct sockaddr_in6));
原因是struct sockaddr_in6
结构包含其他你没有初始化的字段(比如sin6_scope_id
),它可能包含垃圾。
在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; }
当使用“所有本地接口”( INADDR_ANY
)调用bind()
它工作,因为这个巧合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"); }
我遇到了同样的错误。
@askMish的回答是相当正确的。我一开始并不理解,但最终我发现了它。
这通常是由于试图绑定到一个对本地计算机无效的地址造成的。
通常情况下,我们的电脑在某个网关下。
如果我们运行ipconfig
我们会发现IP地址是192.168.something。
这就是我们可以用来在代码中绑定的IP。
当其他人应该连接公共IP(如果你可以上网,你肯定有一个),就像47.93.something,如果他们在你的同一局域网。
你需要在你的网关找到这个IP(可能是你家的路线)。