UdpClient receiveメソッドのタイムアウト値を設定できるかどうか疑問に思っています。
ブロックモードを使用したいのですが、udpによってパケットが失われることがあるので、プログラムudpClient.receiveが永久にハングします。
私がそれをどのように管理できるか良いアイデアはありますか?
Filipが参照しているのは、UdpClient
に含まれるソケット(UdpClient.Client.ReceiveTimeout
)。
非同期メソッドを使用してこれを行うこともできますが、実行を手動でブロックします。
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
}
SendTimeout
のReceiveTimeout
で使用できるSocket
およびUdpClient
プロパティがあります。
5秒のタイムアウトの例を次に示します。
var udpClient = new UdpClient();
udpClient.Client.SendTimeout = 5000;
udpClient.Client.ReceiveTimeout = 5000;
...
実際、タイムアウトに関してはUdpClient
が壊れているようです。データを取得してキューに追加する受信のみを含むスレッドでサーバーを作成しようとしました。私はこの種のことを何年もの間TCPで行ってきました。期待は、メッセージがリクエスターから届くまで、ループが受信でブロックすることです。ただし、タイムアウトを無限に設定しても、次のようになります。
_server.Client.ReceiveTimeout = 0; //block waiting for connections
_server.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 0);
ソケットは約3分後にタイムアウトします。
私が見つけた唯一の回避策は、タイムアウト例外をキャッチしてループを続行することでした。これはマイクロソフトのバグを隠しますが、なぜこれが起こっているのかという根本的な質問に答えることはできません。
あなたはこのようにすることができます:
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000);
使用できるReceiveTimeoutプロパティがあります。