Могу ли я установить тайм-аут для UdpClient в С#?
Мне интересно, могу ли я установить значение тайм-аута для метода приема UdpClient.
Я хочу использовать режим блокировки, но поскольку иногда udp будет потерять пакет, моя программа udpClient.receive будет вешать там навсегда.
какие-нибудь хорошие идеи, как я могу это сделать?
Ответы
Ответ 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);