2

私はC#でサーバーアプリケーションを開発しています。クライアントはサーバーに接続してさまざまな要求を行うことができます。現在、クライアントが接続すると、リクエストを処理するために新しいスレッドが生成されます。TCPClientクラスを使用してクライアント接続を処理しています。私のサーバーは次のように機能します。

  1. クライアントはリクエストでサーバーに接続します
  2. サーバーはリクエストを処理します
  3. サーバーは、クライアントにこれ以上の要求があるかどうかを確認するために待機します
  4. クライアントがタイムアウト期間内に別の要求を行わない場合、サーバーは接続を強制終了します

私の問題は次のとおりです。

TCPClientクラスから取得したNetworkStreamオブジェクトから読み取る場合、使用可能なデータがない場合、NetworkStream Read()メソッドはブロックされません。サーバーがステップ#3に達したときに、NetworkStreamにタイムアウトを設定したいと思います。クライアントがその期間内にそれ以上リクエストを行わない場合、サーバーはそのタイムアウト例外がスローされたときに接続を強制終了する必要があります。サーバーがステップ3に到達すると、ReadTimeoutプロパティを何に設定したかに関係なく、NetworkStream Read()メソッドはブロックされません。誰かが私を助けてくれますか、または私がやろうとしていることをするためのより良い方法を提案できますか?

ありがとう

4

6 に答える 6

2

読み取るデータがない場合、NetworkStream.Read と ReadByte はタイムアウトになるまでブロックする必要があります。呼び出しが何か、おそらくゼロの束を読んでいる可能性がはるかに高いと思います。クライアントから送信されるデータを注意深く確認してください。

于 2009-07-29T18:38:05.447 に答える
0

これはあなたが探しているものですか?

http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.receivetimeout.aspx

GetStream() を使用して TcpClient から NetworkStream を取得し、その上で Read() メソッドを呼び出しているようです。

于 2009-07-29T19:00:24.457 に答える
0

Read() の使用を卒業してBeginRead()メソッドに移行し、並列処理を検討する必要があります。ネットワーク プログラミングは気弱な人向けではありません。

基本的に、データのループ ポーリングを作成する必要はありません。

while(!timedout && !stream.DataAvailable) sleep(0); // This is bad.
if(steam.DataAvailable) steam.Read();

代わりに、このようなことをする方が理にかなっています。リセット イベントを作成し、BeginRead() を呼び出して、コールバックでリセット イベントを解放します。次のようなもの:

void clientThread()
{
   stream.BeginRead(myCallback);
   resetEvent.WaitOne(timeout)
}
void myCallback
{
   resetEvent.Set();
}
于 2009-07-27T18:53:11.980 に答える
0

利用可能なデータがない場合に NetworkStream を明示的に強制的にブロックするには:

TcpClient clientConnection = new TcpClient();

if(clientConnection.Available > 0)
{ 
  //You want to continue execution even though there is no available data to be read from the server then:
  clientConnection.Client.Blocking = false;
}
于 2016-10-31T11:32:02.427 に答える
0

NetworkStream を BufferedStream にラップします。BufferedStream.Read は、少なくとも 1 バイトが使用可能になるまでブロックされます。

于 2009-07-27T19:55:34.053 に答える
-1

NetworkStream.Read() はそれを行う方法を提供しないため、「タイムアウト」を自分で処理する必要があります。

クライアント スレッドでおそらく実行したいことは、NetworkStream.DataAvailable および/または NetworkStream.CanRead をブロッキング/タイムアウト メカニズムと組み合わせて使用​​することです (タイムアウトを指定した WaitHandle.WaitOne 呼び出しを使用するなど)。データを利用可能にする時間のあるクライアント。指定した時間が経過しても何も来ない場合は、接続をシャットダウンして終了します。

于 2009-07-27T18:55:53.753 に答える