条件の1つだけが満たされている場合(データが読み取り可能)、c#でソケットをポーリングする方法があるかどうか疑問に思っています.socket.Pollメソッドは知っていますが、指定された 3 つの条件は、ここで指定されているように true を返します: MSDN: Socket.Poll
6 に答える
MSDN のドキュメントによると、true を返す原因は 3 つあります。
Poll(microSeconds, SelectMode.SelectRead);
Listen()
が呼び出され、接続が保留中の場合- 読み取り可能なデータがある場合
- 接続が閉じられた、リセットされた、または終了した場合
それらを識別できるかどうか見てみましょう。
- が以前に呼び出されたかどうかは常にわかっ
Listen()
ているため、呼び出していない場合はその原因を考慮する必要はありません。 - わかりました、あなたはそれに行きます。
- Poll() 呼び出しにとどまることができず、実際に何が起こったのかを調べる必要があることを意味します。
Poll()
1 つのオプションは、返された直後にソケットの状態を確認することです。
結論:
考慮する必要はない
3. true が返されるたびにソケットの状態をチェックすることで処理できます。
だから私は(未テスト)に行きます:
if (s.Poll(microSeconds, SelectMode.SelectRead)))
{
if (!s.Connected)
// Something bad has happened, shut down
else
// There is data waiting to be read"
}
Socket プロパティ Available を使用できます。読み取り可能なデータ量を返します。
クラス NetworkStream で何かが見つかりました。プロパティNetworkStream.DataAvailableは、データが読み取り可能な場合に true を返します。TcpListener と TcpClient を扱う networkstream のオブジェクトが返されます。これは、ソケットよりも 1 つ高い抽象化レベルです。
Socket から NetworkStream に移行する方法が見つかりませんでした。NetworkStream はソケットを使用しており、ソケットのストリーム表現です。しかし、ネットワークストリームがソケットで何をしているのかわかりません。
基になるハンドルで select() システム コールを使用できます。
Poll() の代わりに Select() メソッドを使用できます。実際、ILSpy (リフレクター ツール) を使用して Socket.Poll を調べると、内部コードがソケットで select を呼び出しています。
さらに、タイトなループで Poll() を呼び出すと、呼び出しごとに新しい IntPtr[] が実行されるため、メモリ割り当てが増加します。Select() を呼び出すと、内部で新しい配列を割り当てる代わりに、配列を再利用できます。