Подтвердить что ты не робот

Могу ли я установить тайм-аут для UdpClient в С#?

Мне интересно, могу ли я установить значение тайм-аута для метода приема UdpClient.

Я хочу использовать режим блокировки, но поскольку иногда udp будет потерять пакет, моя программа udpClient.receive будет вешать там навсегда.

какие-нибудь хорошие идеи, как я могу это сделать?

4b9b3361

Ответ 1

То, что Filip имеет в виду, вложен в сокет, который UdpClient содержит (UdpClient.Client.ReceiveTimeout).

Вы также можете использовать методы async для этого, но вручную заблокируйте выполнение:

var timeToWait = TimeSpan.FromSeconds(10);

var udpClient = new UdpClient( portNumber );
var asyncResult = udpClient.BeginReceive( null, null );
asyncResult.AsyncWaitHandle.WaitOne( timeToWait );
if (asyncResult.IsCompleted)
{
    try
    {
        IPEndPoint remoteEP = null;
        byte[] receivedData = udpClient.EndReceive( asyncResult, ref remoteEP );
        // EndReceive worked and we have received data and remote endpoint
    }
    catch (Exception ex)
    {
        // EndReceive failed and we ended up here
    }
} 
else
{
    // The operation wasn't completed before the timeout and we're off the hook
}

Ответ 2

Существует свойство SendTimeout и ReceiveTimeout, которое можно использовать в Socket UdpClient.

Вот пример 5-секундного тайм-аута:

var udpClient = new UdpClient();

udpClient.Client.SendTimeout = 5000;
udpClient.Client.ReceiveTimeout = 5000;

...

Ответ 3

На самом деле, кажется, что UdpClient нарушается, когда дело доходит до тайм-аутов. Я попытался написать сервер с потоком, содержащим только прием, который получил данные и добавил их в очередь. Я много лет занимался такими вещами, как TCP. Ожидается, что цикл блокируется при получении до тех пор, пока сообщение не поступит от реквестера. Однако, несмотря на установку тайм-аута на бесконечность:

_server.Client.ReceiveTimeout = 0; //block waiting for connections
_server.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 0);

сокет истекает примерно через 3 минуты.

Единственным обходным решением, которое я нашел, было уловить исключение тайм-аута и продолжить цикл. Это скрывает ошибку Microsoft, но не отвечает на основной вопрос, почему это происходит.

Ответ 4

Существует свойство ReceiveTimeout, которое вы можете использовать.

Ответ 5

вы можете сделать вот так:

udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000);