我尝试使用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");
答案 0 :(得分:5)
您应该在此使用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。