Исключение привязки сокета C # UDP - PullRequest
0 голосов
/ 10 ноября 2010

Прежде чем кто-нибудь спросит, я довольно часто просматриваю этот сайт и активно использую Google, но безуспешно искал ответ.

Я пытаюсь создать программу для беспроводной сети (adhoc во всех случаях, кроменазвание).Большая часть сети будет работать с сообщениями TCP, но для определения всех соседних IP-адресов (так как они будут неизвестны при запуске), я выберу UDP Broadcast для начальных сообщений обнаружения.Этот код по большей части не имеет значения, поскольку начальное тестирование, похоже, работает, и в настоящее время я его не называю.

Ниже приведен раздел для получения и регистрации соседних IP-адресов.

protected override void ReceiveMessageUDP()
    {
        while (live)
        {
            try
            {
                UdpListener = new UdpClient(_PORTRECEIVE);
                UdpListener.EnableBroadcast = true;
                Socket socket = UdpListener.Client;
                IPEndPoint endPoint1 = new IPEndPoint(IPAddress.Loopback, _PORTRECEIVE);
                IPEndPoint endPoint2 = new IPEndPoint(IPAddress.Any, _PORTRECEIVE);
                socket.Bind(endPoint2);
                socket.Listen(25);
                Socket connected = socket.Accept();
                byte[] buffer = new byte[1024];
                int length = connected.Receive(buffer);

                IPAddress remoteIP = ((IPEndPoint)connected.RemoteEndPoint).Address;
                if (!ipAddresses.Contains(remoteIP))
                    ipAddresses.Add(remoteIP);

                Message.Add(Encoding.ASCII.GetString(buffer, 0, length));
            }
            catch (SocketException e) { Console.WriteLine(e.ErrorCode); }
            catch (Exception) { }
        }
    }

Я проверил обе IPEndPoints, и независимо от того, как я их настроил, связывание завершается неудачно с SocketException.ErrorCode 10022 Коды ошибок Windows Socket .Это неверный аргумент, но я запутался в том, что это значит, поскольку требуемый аргумент - это EndPoint.

Это не удается при первом запуске, поэтому я не пытаюсь повторно привязать порт.

Ответы [ 2 ]

1 голос
/ 23 августа 2013

Я согласен со Стивом.Тем не менее, вы заявляете, что

«UDP не разрешает привязку или что-то в этом роде».

Но это так.Вы можете привязать любой сокет (UDP или нет) к любому сетевому интерфейсу.Стив дал подсказку, чтобы достичь этого.Вот как я это делаю:

LocalEP = new IPEndPoint(<local IP>, _PORTRECEIVE) ;
listener = New UdpClient(LocalEP) ;

Как указал Стив, после создания экземпляра UdpClient он не позволяет выполнить повторную привязку к другому интерфейсу.Хитрость заключается в том, чтобы конструктор связывался с нужным вам интерфейсом заранее.Замените IP-адресом локального интерфейса, который вы хотите использовать.

Конечно, это полезно, только если у вас есть (или может быть) несколько сетевых интерфейсов и вы хотите использовать определенный.В противном случае я видел, что интерфейс с действительным шлюзом к Интернету обычно является тем, к которому клиенты привязываются по умолчанию.И это обычно правильный.

Роберто

1 голос
/ 10 ноября 2010

Вы уже связали порт с UdpCLient, когда создавали его. Затем вы не можете привязать один и тот же порт к отдельному IPEndPoint.

UdpListener = new UdpClient(_PORTRECEIVE);  // binds port to UDP client
...
IPEndPoint endPoint2 = new IPEndPoint(IPAddress.Any, _PORTRECEIVE);
socket.Bind(endPoint2);  // attempts to bind same port to end point

Если вы хотите сделать это таким образом, соберите и свяжите IPEndPoint, а затем создайте UdpClient с ним вместо порта.

IPEndPoint endPoint2 = new IPEndPoint(IPAddress.Any, _PORTRECEIVE);
socket.Bind(endPoint2);  // bind port to end point

UdpListener = new UdpClient(endPoint2);  // binds port to UDP client via endpoint

Я не уверен, почему вы также настраиваете другую конечную точку endPoint1 на том же порту. Это может вызвать проблемы в будущем, если и когда вы попытаетесь использовать это.

...