StreamWriter не будет сбрасываться в NetworkStream
Используя 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 к серверу и портом непосредственно и ввожу команды, я получаю немедленный ответ.
Если я позвоню serverWriter.Flush()
явно, вместо использования AutoFlush
собственность, я все еще блокирую и никогда не получаю ответ.
Любые идеи, почему я не получаю ответ на сервер с использованием этого подхода?
Спасибо!
Постановили:
Приведенный выше код работает для меня, поэтому я вернулся и основал этот код на код, который не будет работать.
В коде, который зависает, я все еще использовал цикл тайм-аута с 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.