bind() 失败,出现 Windows 套接字错误 10049

问题描述 投票:0回答:5

我尝试使用 C 语言使用 IPv6 和 UDP 制作客户端/服务器程序。当程序绑定套接字时,它返回 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");
c windows sockets bind
5个回答
5
投票

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

您应该在这里使用

PF_INET
而不是
AF_INET
。它们具有相同的值,但您在此不指定地址族
AF
,而是指定协议族
PF
。这只是一个风格推荐。

我建议

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

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

5
投票

在使用

sockaddr_in6
结构之前,您必须将
memset
设置为零:

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

原因是

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


2
投票

我也遇到过同样的错误。

@askMish 的回答很对。我一开始没明白,但后来我明白了。

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

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

如果我们运行

ipconfig
,我们会发现IP地址是192.168.something。

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

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

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


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

0
投票

我认为问题可能在于 IPv6 的 UDP 协议规范。它是 IPv4。还要确保端口在您的系统上有效且处于活动状态。因此套接字定义应类似于以下示例

进口插座

udp_socket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) udp_socket.bind(('169.254.33.36',5353))

© www.soinside.com 2019 - 2024. All rights reserved.