StreamWriter не будет сбрасываться в NetworkStream - PullRequest
2 голосов
/ 11 сентября 2009

Использование 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(), но я всегда буду тайм-аут; Я никогда не получаю ответ.

Если я напрямую подключаюсь к серверу, портирую и ввожу команды, я получаю немедленный ответ.

Если я вызываю serverWriter.Flush() явно, вместо использования свойства AutoFlush, я все равно блокирую и никогда не получаю ответ.

Есть идеи, почему я не получаю ответ на сервер, использующий этот подход?

Спасибо!

Решено:

Приведенный выше код работает для меня, поэтому я вернулся и добавил этот код к коду, который не будет работать.

В коде, который зависает, я все еще использовал цикл тайм-аута с serverReader.Peek (). Peek () всегда возвращает -1, даже если в буфере есть данные для чтения !! Замена цикла Peek () блокирующим вызовом ReadLine () решает мою проблему.

Первоначально я включил цикл ожидания, потому что приложение является многопоточным, и я не хотел блокировать. Мне придется вернуться к этой проблеме и посмотреть, как я могу решить синхронизацию потоков без использования Peek ().

Спасибо всем, хорошие ответы!

Ответы [ 3 ]

6 голосов
/ 11 сентября 2009

Я сомневаюсь, что это проблема StreamWriter ... но есть простой способ выяснить это. Скачайте WireShark и посмотрите, что на самом деле приходит и выходит в сеть Это, безусловно, самый простой способ выяснить, что происходит.

2 голосов
/ 11 сентября 2009

Попробуйте "имя пользователя authinfo \ r \ n". RFC говорит, что командные строки NNTP должны заканчиваться CR-LF.

1 голос
/ 10 августа 2010

Код выше работает для меня, поэтому я вернулся и основал этот код на код, который не будет работать.

В коде, который зависает, я все еще использовал цикл тайм-аута с serverReader.Peek (). Peek () всегда возвращает -1, даже если в буфере есть данные для чтения !! Замена цикла Peek () блокирующим вызовом ReadLine () решает мою проблему.

Первоначально я включил цикл тайм-аута, потому что приложение является многопоточным, и я не хотел блокировать. Мне придется вернуться к этой проблеме и посмотреть, как я могу решить синхронизацию потоков без использования Peek ().

Спасибо всем, хорошие ответы!

...