StreamWriterはNetworkStreamにフラッシュしません
-
06-07-2019 - |
質問
StreamWriter
を使用して NetworkStream
に書き込み、 StreamReader
を使用して応答を読み取ります。アプリはコマンドを送信し、応答をニュースサーバーに読み取ります。
簡略化されたコード(エラー処理などを除く):
tcpClient = new TcpClient();
tcpClient.Connect(Name, Port);
networkStream = tcpClient.GetStream();
serverReader = new StreamReader(networkStream, Encoding.Default);
serverWriter = new StreamWriter(networkStream, Encoding.ASCII) {
AutoFlush = true
};
// reads the server's response to the connect: "200 news.newsserver.com"
// commenting out these lines doesn't solve the problem
while (serverReader.Peek() > -1) {
serverReader.ReadLine();
}
serverWriter.WriteLine("authinfo user username");
// expect response "381 more authentication required", but code just blocks
string response = serverReader.ReadLine();
コードはその最後の行でブロックし、おそらくネットワークストリームが応答を送信するのを待っています。
serverReader.Peek()
を使用してタイムアウトループを設定することで、アプリのハングを回避できますが、常にタイムアウトします。応答がありません。
サーバーとポートに直接telnetで接続してコマンドを入力すると、すぐに応答があります。
autoFlush
プロパティを使用する代わりに、明示的に serverWriter.Flush()
を呼び出した場合、ブロックし、応答を受け取りません。
このアプローチを使用してサーバーへの応答を得られない理由は何ですか?
ありがとう!
解決済み:
上記のコードは私のために機能します ので、私は戻って、機能しないコードにそのコードを構築しました。
ハングするコードでは、serverReader.Peek()でタイムアウトループを使用していました。 Peek()は、読み取るデータがバッファにある場合でも、常に-1を返します!! Peek()ループをReadLine()のブロック呼び出しに置き換えると、問題が解決します。
もともとアプリがマルチスレッドであるため、タイムアウトループを挿入しましたが、ブロックしたくありませんでした。この問題を再検討し、Peek()を使用せずにスレッドタイミングを解決する方法を確認する必要があります。
ありがとう、良い答え!
解決 3
上記のコードは機能します、私にとっては機能するので、私は戻ってそのコードを機能しないコードに構築しました。
ハングするコードでは、serverReader.Peek()でタイムアウトループを使用していました。 Peek()は、読み取るデータがバッファにある場合でも、常に-1を返します!! Peek()ループをReadLine()のブロック呼び出しに置き換えると、問題が解決します。
もともとアプリがマルチスレッドであるため、タイムアウトループを挿入しましたが、ブロックしたくありませんでした。この問題を再検討し、Peek()を使用せずにスレッドタイミングを解決する方法を確認する必要があります。
ありがとう、良い答え!
他のヒント
問題は StreamWriter
であるとは思いませんが、簡単な方法を見つけることができます。 WireShark をダウンロードし、ネットワーク上で実際に送受信されるものを確認します。これは、何が起こっているのかを知る最も簡単な方法です。
" authinfo user username \ r \ n"を試してください。 RFCでは、NNTPコマンドラインはCR-LFで終了する必要があると述べています。