Прослушиватель C # UDP отключен от блокировки? или предотвратить блокировку revceiving

#c# #udp

#c# #udp

Вопрос:

Я искал предыдущие проблемы, подобные моей, здесь, но, похоже, я не могу найти ответ, который мне нужен.

Моя цель — не допустить зависания моего UDP-прослушивателя. У меня есть UDP-прослушиватель, который ожидает сообщений, но если нечего получать, он просто зависает там.

Я прочитал другие потоки, и они говорят, что мне нужно установить для блокировки значение false, но я не могу найти, как это установить. Извините, я просто новичок в C # и программировании сокетов.

Вот часть моего прослушивателя:

 while (true)
{
    try
    {
        byte[] data = listener.Receive(ref groupEP);

        IPEndPoint newuser = new IPEndPoint(groupEP.Address, groupEP.Port);
        string sData =  (System.Text.Encoding.ASCII.GetString(data));

    }
    catch (Exception e)
    {
    }
}
  

Моя проблема в том, что он просто зависает в следующей строке:

 byte[] data = listener.Receive(ref groupEP);
  

Ответ №1:

Используйте доступное свойство UdpClient (если это то, что вы используете), чтобы определить, есть ли у вас данные в сетевой очереди для чтения.

 while (true)
{
    try
    {
        if (listener.Available > 0) // Only read if we have some data 
        {                           // queued in the network buffer. 
            byte[] data = listener.Receive(ref groupEP);

            IPEndPoint newuser = new IPEndPoint(groupEP.Address, groupEP.Port);
            string sData =  (System.Text.Encoding.ASCII.GetString(data));
        }
    }
    catch (Exception e)
    {
    }
}
  

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

1. Но тогда, без какого-либо разрыва цикла, разве это на самом деле не соответствует исходному коду? лучше блокировать при получении (), а не записывать процессор с непрерывными проверками if (доступно) в цикле, не так ли?

2. Добавьте предложение Thread.Sleep(10); inside try{} , и процессорная загрузка полностью исчезнет..

Ответ №2:

         UdpClient client = new UdpClient();
        //Some code goes here ...
        client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 2000);
  

// Это довольно ясно и просто.

Ответ №3:

Вы используете блокирующие версии Receive / Send. Рассмотрите возможность использования асинхронных версий (ReceiveAsync / BeginReceive) вместо этого.

https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.udpclient?view=netcore-3.1

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

1. На связанной странице написано: Метод Receive блокирует выполнение до тех пор, пока не будет получено сообщение, чего именно пытается избежать вопрос

Ответ №4:

 TestHost.Client.Blocking = false;
  

Вам необходимо получить доступ к объекту ‘Socket’, расположенному под объектом UdpClient (‘TestHost’ в подробном примере ниже), чтобы получить доступ к свойству ‘Blocking’, как показано:

 int Port = 9020;    //Any port number you like will do
IPAddress ActiveIPaddress = new IPAddress(new byte[] { 192, 168, 3, 10 }); //Any IPaddress you need will do
IPEndPoint HostEP = new IPEndPoint(ActiveIPaddress, Port);
UdpClient TestHost = new UdpClient(Global.HostEP);
TestHost.Client.Blocking = false;
  

введите описание изображения здесь