2016-08-03 14 views
1

私は、読み込むバイト数が2バイトのヘッダーで始まるTCPサーバーを作成しました。ストリームから読み取り、クライアントに応答を返すと、NetworkStreamとTcpClientの両方が破棄されます。問題は、Thread.Sleep()行のコメントを解除しない限り、クライアントが私の応答を受け取っていないように見えることです。NetworkStream Sleep()の問題

using (var tcpClient = await tcpServer.AcceptTcpClientAsync()) 
{ 
    tcpClient.NoDelay = true; 

    using (var stream = tcpClient.GetStream()) 
    { 
     var twoBytesHeader = new TwoByteHeader(); 
     var headerBuffer = new byte[twoBytesHeader.HeaderLength]; 

     using (var binaryReader = new BinaryReader(stream, Encoding.ASCII, true)) 
     { 
      headerBuffer = binaryReader.ReadBytes(twoBytesHeader.HeaderLength); 

      int newOffset; 
      var msgLength = twoBytesHeader.GetMessageLength(headerBuffer, 0, out newOffset); 

      var buffer = binaryReader.ReadBytes(msgLength); 

      string msgASCII = Encoding.ASCII.GetString(buffer); 

      var bufferToSend = await ProcessMessage(msgASCII); 

      using (var binaryWriter = new BinaryWriter(stream, Encoding.ASCII, true)) 
      { 
       binaryWriter.Write(bufferToSend); 
       binaryWriter.Flush(); 
      } 

      //Thread.Sleep(1000); 
     } 
    } 
} 

Sleepのコメントが解除されると、クライアントは応答を受けて、クライアントの接続が切断されたことを示します。この現象の原因を特定できません。

+0

データを送信する際にエラーがないことを確認する必要がある場合は、asyncが答えになるとは限りません。送信し、送信したことを確認してから閉じることができますか? – BugFinder

+0

ありがとうございます。この場合、私はWriteAsyncを待っているので、すべてのバイトが送信されるまで待ってから接続を閉じます。私が間違っていることが他にもあるはずです。 – GAG

答えて

2

あなたは、指定されたバイト数で読み込みが行われると想定しています。代わりに、少なくとも1バイトを読み込みます。あなたのコードはそれに対処できる必要があります。 BinaryReader.ReadBytesを使用すると、正確なバイト数を読み取り、定型コードの一部を取り除くことができます。

また、最悪の場合のエンコードであるASCIIエンコードは使用しないでください。

+0

ストリームを使って読むことで起こりうる問題を指摘してくれてありがとう、私はそれを考慮に入れます。エンコードに関しては、クライアントがASCIIでエンコードされたメッセージを送信するため、私は選択肢がありません。とにかく、私はまだ理解できません。なぜ、stream.Flush()の後にSleep()を置くと、クライアントは応答を受け取るのですか?私はNagleのアルゴリズムについて読んだことがありますが、NoDelayプロパティを設定した場合と同様にFlushが動作すると仮定します。 – GAG

+0

おそらくクライアントが壊れていますか?コードを投稿します。私が説明した問題は、サーバーがクラッシュし、頼りないメッセージを送信する可能性があります。だから、とにかく修正して新しいコードを投稿するべきだろう。 NetworkStreamのフラッシュは何もしません。何も変えることはできません。 – usr

+0

問題は、クライアントが私がアクセスできない外部アプリケーションだということです。私がテスト用に書いたシンプルなクライアントはうまく動作します。あなたが提案した変更を行い、役立つかどうかを確認します。 – GAG