bind () échoue avec l’erreur de socket Windows 10049

J’essaie de créer un programme client / serveur en C avec IPv6 et UDP. Lorsque le programme lie le socket, il renvoie le WSAError 10049. Je sais que c’est un problème avec le nom de l’adresse, mais ne voyez pas le problème. J’espère que quelqu’un peut aider.

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

Cela résulte normalement d’une tentative de liaison à une adresse non valide pour l’ordinateur local. .

Vous devez utiliser PF_INET ici au lieu de AF_INET . Ils ont la même valeur, mais vous ne spécifiez pas de famille d’adresses AF ici, vous spécifiez une famille de protocoles PF . Ceci est juste une recommandation de style.

Je suggérerais de mettre à zéro les tableaux ci-dessous, structures:

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

Avant de pouvoir utiliser la structure sockaddr_in6 , vous devrez la memset à zéro:

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

La raison en est que la struct sockaddr_in6 contient d’autres champs que vous sin6_scope_id pas (tels que sin6_scope_id ) et qui peuvent contenir des sin6_scope_id .

J’ai eu ce même code d’erreur lors de l’appel de bind() sous Windows.

La raison dans mon cas n’était pas la même que dans le code de l’affiche initiale, mais je suppose que d’autres auront fait la même erreur que moi:

J’ai généré l’adresse locale sur laquelle je souhaite inet_addr() le serveur localement à l’aide de la fonction inet_addr() . J’ai affecté ce résultat à la structure d’adresse locale struct sockaddr_in localaddr cette façon:

localaddr.sin_addr.s_addr = htonl(inaddr);

Mais inet_addr() renvoie déjà l’adresse dans l’ordre des octets, de sorte que l’appel htonl(inaddr) était erroné dans mon code et provoquait l’erreur 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; } 

Lors de l’appel de bind() aide de “toutes les interfaces locales” ( INADDR_ANY ), cela a fonctionné à cause de cette coïncidence. 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"); } 

J’ai fait face à la même erreur.

La réponse de @askMish est tout à fait correcte. Je ne l’ai pas compris en premier lieu, mais je le découvre finalement.

Cela résulte normalement d’une tentative de liaison à une adresse non valide pour l’ordinateur local.

Normalement, nous avons notre ordinateur sous une passerelle.

Si nous ipconfig nous trouverons que l’adresse IP est 192.168.

Donc, c’est l’IP que nous pourrions utiliser pour lier le code.

Tandis que d’autres devraient se connecter avec l’IP publique (si vous pouvez surfer sur Internet, vous en avez une à coup sûr.)

Vous devez trouver cette adresse IP à votre passerelle (éventuellement la route de votre famille).