StreamReader с TcpClient возвращает неверные строки - PullRequest
0 голосов
/ 20 февраля 2012

Я использую TcpClient и NetworkStream, чтобы инициировать соединение с POP-сервером для аутентификации.Плохая практика, полезная для обучения.

Когда я подключаюсь к серверу POP через Telnet, первоначально получается ответ:

+OK Dovecot Ready

Пользователь вводит имя пользователя

+OK

Пользователь вводитпроход, который проверяется +OK, если он действителен -N, если нет

Моя программа подключается к серверу POP, открывает StreamReader и Writer, записывает все эти данные и проверяет ответ.

   using (TcpClient client = new TcpClient("host.university.ie", 110)) {
        using (NetworkStream stream = client.GetStream()) {
        using (StreamReader reader = new StreamReader(stream)) {
        using (StreamWriter writer = new StreamWriter(stream)) {
            string response = reader.ReadLine();
            writer.Write("USER " + username );
            response = reader.ReadLine();
            writer.Write("PASS " + password );
            string response = reader.ReadLine();
            Response.Write(@"<script language='javascript'>alert('The following response as been received: \n" + response + " .');</script>");
            isValid = response[ 0 ].Equals('+');
            writer.WriteLine("quit\n");
        }
       }
      }
     }
    }

Однако, когда я ввожу этот код, запрос переходит в бесконечный цикл.Смущает то, что когда я уменьшаю количество обращений к reader.ReadLine () до одного, он возвращает «+ OK Dovecot Ready»!Поэтому он подключается к серверу POP, но после этого работать не будет.У кого-нибудь есть идеи, что может быть причиной этого?

Ответы [ 3 ]

2 голосов
/ 20 февраля 2012

Нет, это не бесконечный цикл.Второй вызов reader.ReadLine() никогда не вернется, поскольку вы не завершили отправку команды USER на сервер.Вы должны отправлять символы перевода строки, используя .WriteLine вместо .Write

Попробуйте:

writer.WriteLine("USER " + username);
writer.Flush();

и это:

writer.WriteLine("PASS " + password);
writer.Flush();

РЕДАКТИРОВАТЬ: добавлены вызовы в .Flush согласно предложению spender .

1 голос
/ 20 февраля 2012

В дополнение к ответу @ atornblad, рассмотрите writer.Flush() после того, как вы напишете в поток и нуждаетесь в ответе.

0 голосов
/ 20 февраля 2012

Попробуйте проверить: CanWrite и CanRead в потоке и проверьте вашу кодировку: См .: http://msdn.microsoft.com/de-de/library/system.net.sockets.tcpclient.getstream.aspx

Некоторые дополнительные вопросы: Где находится ваш бесконечный цикл?Я не вижу никаких циклов в вашем коде.ReadLine - это метод блокировки.Может быть, конец символа строки является проблемой?Вместо этого попробуйте прочитать (), чтобы получить символьный вывод.

Где он возвращает "+ OK Dovecot Ready"?Если это в вашем графическом интерфейсе, попробуйте вызвать .Refresh для элемента, который должен отображать результат, потому что ваш поток GUI может быть заблокирован следующими блокирующими вызовами ReadLine ().

Это \ n по назначению?

writer.WriteLine("quit\n"); 

Это приводит к двойному завершению строки.

И попробуйте использовать

.Flush() after writing to your stream.
...