Реализация пробивки отверстий UDP

Я пытаюсь выполнить пробивание отверстий UDP. Я основываю свою теорию на этой статье и этой странице WIKI , но у меня возникли некоторые проблемы с ее кодированием на C #. Вот моя проблема:

Используя код, который был размещен здесь , теперь я могу подключиться к удаленному компьютеру и прослушивать один и тот же порт для входящих подключений (привязать 2 UDP-клиента к одному и тому же порту) .

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

Если я привяжу к порту другого клиента, ни один из клиентов не получит данные.

Ниже приведены 2 фрагмента кода, которые показывают мою проблему.Первый подключается к удаленному серверу для создания правила на устройстве NAT, а затем в другом потоке запускается прослушиватель для захвата входящих пакетов. Затем код отправляет пакеты на локальный IP-адрес, чтобы прослушиватель их получил. Второй только отправляет пакеты на локальный IP-адрес, чтобы убедиться, что это работает. Я знаю, что это не настоящая пробивка дыр, так как я отправляю пакеты себе, вообще не живя на устройстве NAT. На данный момент я столкнулся с проблемой, и я не думаю, что все будет по-другому, если я буду использовать для подключения компьютер, не подключенный к устройству NAT.

[РЕДАКТИРОВАТЬ] 4 февраля 2012 г. Я попытался использовать другой компьютер в своей сети и WireShark (сниффер пакетов), чтобы проверить слушателя. Я вижу пакеты, поступающие с другого компьютера, но не получаемые UDP-клиентом слушателя (udpServer) или UDP-клиентом отправителя (клиент).

[РЕДАКТИРОВАТЬ] 05.02.2010 Теперь я добавил вызов функции для закрытия первого клиента UDP после начальной отправки и получения пакетов, живущих только со вторым клиентом UDP для прослушивания порта. Это работает, и я могу получать пакеты изнутри сети на этот порт. Теперь я попытаюсь отправлять и получать пакеты из-за пределов сети. Я опубликую свои выводы, как только что-нибудь найду.

Используя этот код, я получаю данные о слушающем клиенте:

static void Main(string[] args)
{
    IPEndPoint localpt = new IPEndPoint(Dns.Resolve(Dns.GetHostName()).AddressList[0], 4545);

    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); //this line will block forever
        Console.WriteLine("Receive from " + inEndPoint + " " + Encoding.ASCII.GetString(buffer) + ".");
    });

    Thread.Sleep(1000);

    UdpClient udpServer2 = new UdpClient(6000);

    // the following lines work and the data is received
    udpServer2.Connect(Dns.Resolve(Dns.GetHostName()).AddressList[0], 4545);
    udpServer2.Send(new byte[] { 0x41 }, 1);

    Console.Read();
}

Если я использую следующий код, после соединения и передачи данных между моим клиентом и сервером слушающий UDP-клиент ничего не получит:

static void Main(string[] args)
{
    IPEndPoint localpt = new IPEndPoint(Dns.Resolve(Dns.GetHostName()).AddressList[0], 4545);

    //if the following lines up until serverConnect(); are removed all packets are received correctly
    client = new UdpClient();
    client.ExclusiveAddressUse = false;
    client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
    client.Client.Bind(localpt);
    remoteServerConnect(); //connection to remote server is done here
                           //response is received correctly and printed to the console

    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); //this line will block forever
        Console.WriteLine("Receive from " + inEndPoint + " " + Encoding.ASCII.GetString(buffer) + ".");
    });

    Thread.Sleep(1000);

    UdpClient udpServer2 = new UdpClient(6000);

    // I expected the following line to work and to receive this as well
    udpServer2.Connect(Dns.Resolve(Dns.GetHostName()).AddressList[0], 4545);
    udpServer2.Send(new byte[] { 0x41 }, 1);

    Console.Read();
}

21
задан Community 23 May 2017 в 12:09
поделиться