C # UdpClient — отправка и получение в программу на локальном компьютере

#c# #udp

#c# #udp

Вопрос:

На моем компьютере запущены две сторонние программы, которые взаимодействуют друг с другом через UDP. Программа A — это просто приложение с пользовательским интерфейсом, которое подключается через UDP и позволяет пользователю отправлять определенные шестнадцатеричные команды программе B, которая отправляет обратно некоторое подтверждение в шестнадцатеричном формате. Я знаю, что программа B получает на порт 11001 и отправляет на порт 11000. Для начала я пытаюсь воссоздать программу A на C # в качестве консольного приложения. Я написал следующий код:

 using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            network udpNetwork = new network();
            Console.WriteLine("Hello World!");
            udpNetwork.StartListener();
        }
    }

    class network
    {
        private const int sendPort = 11001; //Port to transmit to
        private const int receivePort = 11000; //Port to receive on

        public void StartListener()
        {
            string IP_Address = Dns.GetHostByName(Environment.MachineName).AddressList[1].ToString();
            IPAddress broadcast = IPAddress.Parse(IP_Address); //create IP address
            IPEndPoint endpointSend = new IPEndPoint(broadcast, sendPort);
            IPEndPoint endpointReceive = new IPEndPoint(broadcast, receivePort);

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

            var packetData = new byte[] { 0x1F, 0x7F, 0x80, 0x1F, 0xFF };
            
            try
            {
                udpServer.Connect(endpointSend);
                udpServer.Send(packetData, packetData.Length);
                udpServer.Close();

                UdpClient udpReceive = new UdpClient(AddressFamily.InterNetwork);
                udpReceive.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                udpReceive.Client.Bind(endpointReceive);
                Byte[] receiveBytes = udpReceive.Receive(ref endpointReceive);
                string returnData = Encoding.ASCII.GetString(receiveBytes);
                Console.WriteLine("This is the message you received "  
                                          returnData.ToString());
            } catch(Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    }
}
 

Код выполняется нормально до строки Byte[] receiveBytes = udpReceive.Receive(ref endpointReceive); , на которой он зависает. Я читал, что эта функция блокируется, что означает, что программа ожидает данных, но, очевидно, не получает их. Программа B, прослушивающая порт 11001, должна отправить ответ после того, как я отправил packetData, но этого не делает. Мне все равно не нужно использовать программу B, чтобы подтвердить, что она получает данные, которые я отправляю. Как я могу подтвердить, что программа B получает мои данные в первую очередь, или у меня есть какая-то другая проблема с моим кодом?

Редактировать:

Я отредактировал свой код, чтобы использовать IPV4, а не IPV6, в соответствии с предложением Jdweng. (Показано исправленным в приведенном выше фрагменте кода). Однако программа B по-прежнему не получает никаких данных, которые я могу подтвердить с помощью TCPView. После запуска программы из Visual Studio 2019 TCPView показывает, что программой B. не было получено пакетов.

Комментарии:

1. Вы используете метод блокировки (синхронный), который будет ждать, пока данные не будут получены. Таким образом, вы не получаете никаких данных. Вы должны использовать IPV4 (не IPV6): AddressFamily . InterNetworkV6. Также нулевой индекс равен IPV6, и вы должны использовать индекс один для IPV4: список адресов [1]

2. @jdweng Хорошо, отредактировали код, чтобы использовать IPV4. Я использовал TCPView, чтобы проверить, получает ли программа B какие-либо пакеты, но это все еще не так.

3. Что такое IP-адрес (многоадресная рассылка с 224 по 239)? Отправляете ли вы широковещательный или обычный UDP. Я бы использовал сниффер, такой как wireshark или fiddler, и посмотрел, правильно ли вы отправляете сообщения. Затем, после того, как вы получите отправку, попробуйте получить.

4. Если я запущу ipconfig/all , IPv4-адрес будет 192.168.11.113, а маска подсети — 255.255.255.0. Я отправляю широковещательный UDP — как только у меня будет что-то базовое, я хочу иметь возможность отправлять данные при нажатии кнопки.

5. Таким образом, это не многоадресная рассылка. Тогда широковещательный адрес будет 192.169.11.255. Вы видите, что получаете сообщения с помощью сниффера. Широковещательный IP-адрес — это адрес 255 подсети. В противном случае он не транслируется.