Подключение двух клиентов UDP к одному порту (отправка и получение) - PullRequest
8 голосов
/ 03 февраля 2012

Я попробовал предложение из этого вопроса с очень небольшим успехом.

Пожалуйста ... любая помощь будет высоко оценена!1007 *

static void Main(string[] args)
{

    IPEndPoint localpt = new IPEndPoint(IPAddress.Any, 6000);

    UdpClient udpServer = new UdpClient(localpt); 
    udpServer.Client.SetSocketOption(
        SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

    UdpClient udpServer2 = new UdpClient();
    udpServer2.Client.SetSocketOption(
        SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

    udpServer2.Client.Bind(localpt); // <<---------- Exception here
}

Ответы [ 4 ]

24 голосов
/ 03 февраля 2012

Вы должны установить опцию сокета перед привязкой.

    static void Main(string[] args)
    {
        IPEndPoint localpt = new IPEndPoint(IPAddress.Any, 6000);

        UdpClient udpServer = new UdpClient();
        udpServer.Client.SetSocketOption(
            SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
        udpServer.Client.Bind(localpt);

        UdpClient udpServer2 = new UdpClient();
        udpServer2.Client.SetSocketOption(
            SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

        udpServer2.Client.Bind(localpt); // <<---------- No Exception here

        Console.WriteLine("Finished.");
        Console.ReadLine();
    }

Или более наглядный пример:

    static void Main(string[] args)
    {
        IPEndPoint localpt = new IPEndPoint(IPAddress.Loopback, 6000);

        ThreadPool.QueueUserWorkItem(delegate
        {
            UdpClient udpServer = new UdpClient();
            udpServer.ExclusiveAddressUse = false;
            udpServer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            udpServer.Client.Bind(localpt);

            IPEndPoint inEndPoint = new IPEndPoint(IPAddress.Any, 0);
            Console.WriteLine("Listening on " + localpt + ".");
            byte[] buffer = udpServer.Receive(ref inEndPoint);
            Console.WriteLine("Receive from " + inEndPoint + " " + Encoding.ASCII.GetString(buffer) + ".");
        });

        Thread.Sleep(1000);

        UdpClient udpServer2 = new UdpClient();
        udpServer2.ExclusiveAddressUse = false;
        udpServer2.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
        udpServer2.Client.Bind(localpt);

        udpServer2.Send(new byte[] { 0x41 }, 1, localpt);

        Console.Read();
    }
2 голосов
/ 03 февраля 2012

Я посмотрел ваше сообщение об ошибке, и это объясняет, что это за ошибка и почему она происходит.

Вот точное сообщение об ошибке и причина WSAEACCES 10013 ( MSDN )

В доступе отказано.

Была сделана попытка доступа к сокету способом, запрещенным его разрешения на доступ. Пример использования широковещательного адреса для sendto без разрешения широковещания, установленного с помощью setsockopt (SO_BROADCAST).

Другая возможная причина ошибки WSAEACCES заключается в том, что при привязке функция вызывается (в Windows NT 4.0 с SP4 и выше), другая приложение, служба или драйвер режима ядра связаны с тем же адрес с эксклюзивным доступом. Такой эксклюзивный доступ является новой функцией Windows NT 4.0 с пакетом обновления 4 и более поздних версий, и реализуется с помощью Параметр SO_EXCLUSIVEADDRUSE.

0 голосов
/ 17 сентября 2016

Чтобы устранить исключение WSAEACCESS 10013 ( MSDN ) в приложении UDP, вы можете попробовать

udpServer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
0 голосов
/ 03 февраля 2012

Даже изменяя ваш код, чтобы я мог передать IP-адрес, я получаю то же сообщение об ошибке, что кажется, что вы не можете привязать к одному и тому же порту, и можно использовать только один порт Вот пример кода, который я использовал на вашем примере и изменил для захвата моего ip с моего локального компьютера.

        IPAddress ipAddress = Dns.Resolve(Dns.GetHostName()).AddressList[0];
        IPEndPoint ipLocalEndPoint = new IPEndPoint(ipAddress, 11000);

        //IPEndPoint localpt = new IPEndPoint(ipLocalEndPoint);

        UdpClient udpServer = new UdpClient(ipLocalEndPoint);
        udpServer.Client.SetSocketOption(
            SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
        udpServer.Connect(ipLocalEndPoint);
        UdpClient udpServer2 = new UdpClient();
        udpServer2.Client.SetSocketOption(
            SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

        udpServer2.Client.Bind(ipLocalEndPoint); // <<---------- Exception here

это вызовет исключение для метода Bind () .. извините.

...