Не удалось получить идентификатор аппаратной привязки подключение завершено код ошибки 10049

Я пытался написать простую программу чата на C ++ и столкнулся с проблемой сокетов. Следующий код возвращается

Последний код ошибки был (1): 0
Последний код ошибки был (2): 0
Последний код ошибки был (3): 10049
Последний код ошибки был (4): 10022

После проверки страницы MSDN на наличие ошибок WSA я обнаружил, что 10022 был для недопустимого аргумента, а 10049 пытался привязаться к недоступному адресу. Я пришел к выводу, что ошибка 10049 вызывала ошибку 10022, когда я пытался прослушивать несвязанный сокет.

После этого попробовал несколько разных адресов, чтобы найти ЛЮБОЙ доступный адрес, включая 127.x.x.x, 192.168.x.x, 0.0.0.0, ни один из которых не работал. Я прыгнул в CMD и увидел, что эти процессы используют другие процессы. Может ли кто-нибудь указать мне правильное направление, чтобы найти корень этой проблемы?

Решение

Во-первых, общее примечание: вам нужно проверять возвращаемое значение каждой вызываемой функции и распечатывать значение WSAGetLastError () только в том случае, если возвращаемое значение указывает на то, что функция вернула ошибку. В противном случае вы можете запутаться, только взглянув на значения кода ошибки, оставшиеся от предыдущих вызовов, и не будете иметь ничего общего с последним вызовом. То есть вместо этого:

bind(sock_CONNECTION, (SOCKADDR *)&ADDRESS, AddressSize);
printf(“Last error code was(3): %d
“, WSAGetLastError());

Тем не менее, я думаю, что конкретная проблема здесь:

ADDRESS.sin_addr.s_addr = inet_pton(AF_INET, (const CHAR*)&addr, &buffer);

inet_pton() не возвращает адрес; скорее он возвращает «1, если адрес был действительным для указанного семейства адресов, или 0, если адрес не был разбираем в указанном семействе адресов, или -1, если произошла какая-то системная ошибка (в этом случае будет установлено значение errno)». Таким образом, значение, которое вы записываете в ADDRESS.sin_addr.s_addr, равно -1, 0 или 1; ни один из них не является допустимым адресом, который bind () захочет использовать. (Ну, на самом деле 0 может быть использовано; см. Ниже, но вызов все еще не так)

Читайте также:  Windows 10 не может продолжить выполнение кода, поскольку xinput1_3.dll отсутствует в системе

Правильный способ вызова inet_pton () будет выглядеть примерно так:

int result = inet_pton(AF_INET, addr, &ADDRESS.sin_addr);
if (result != 1) printf(“inet_pton() failed, error code %d
“, WSAGetLastError());

// INADDR_ANY (aka 0) means “I don’t care which network interface, accept connections on any of them”ADDRESS.sin_addr.s_addr = INADDR_ANY;

Код с серверной реализацией взят из http://www.planetchili.net/forum/viewtopic.php?f=3&т = 3433

bind() Функция используется для указания того, какой адрес серверной системы используется для приема соединений от удаленных клиентов, а не для указания, какому удаленному клиенту разрешено подключаться к серверу. bind() Функция может использоваться только с адресами, которые действительны для самого сервера, но не для адресов удаленных устройств или хостов.

Чтобы определить, какому удаленному хосту разрешено подключаться к вашему серверу, вам необходимо принять подключение и подтвердить удаленный адрес в это время. Если адрес не правильный, соединение закрывается.

В общем, вы хотите использовать INADDR_ANY если ваш сервер не является многодомным (более одного физического подключения к нескольким сетям), и только тогда, если вы пытаетесь ограничить подключения к одной из сетей, к которым подключен ваш сервер.

Другие решения

вы получите список адресов ip4 / ip6, затем вы можете выбрать один из них и привязать свой сервер, однако этот метод действительно скучный, поэтому альтернативой является привязка к INADDR_ANY так что вы позволяете системе делать работу за вас.

вам нужно только с клиента ввести адрес сервера и порт и подключиться.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *