Не могу получить более одного сообщения, используя TcpClient и StreamReader - PullRequest
1 голос
/ 30 апреля 2011

Мне нужно получить второй ответ от серверного приложения.Когда я впервые подключаюсь к серверу приложения, я получаю ответ.Но когда я пытаюсь отправить другое сообщение, я не могу его получить.

Я пытался найти решение, но ничего не могу найти.Я считаю, что проблема в том, что указатель на моем читателе все еще в конце.Вот почему я не могу прочитать следующий ответ.Вот мой код:

public static void XConn()
{
    TcpClient client = new TcpClient();
    client.Connect("xxx.xxx.xxx.xxx",xx); // i cant show the IP sorry
    Stream s = client.GetStream();
    StreamReader sr = new StreamReader(s);
    StreamWriter sw = new StreamWriter(s);

    String r = "";
    sw.AutoFlush = true;      

    sw.WriteLine("CONNECT\nlogin:xxxxxxx \npasscode:xxxxxxx \n\n" + Convert.ToChar(0)); // cant show also

    while(sr.Peek() >= 0)
    {
        r = sr.ReadLine();
        Console.WriteLine(r);
        Debug.WriteLine(r);
        if (r.ToString() == "")
            break;
    }

    sr.DiscardBufferedData();

    //get data needed, sendMsg is a string containing the message i want to send
    GetmsgType("1");
    sw.WriteLine(sendMsg);

    // here i try to receive again the 2nd message but it fails =(
    while(sr.Peek() >= 0)
    {
        r = sr.ReadLine();
        Console.WriteLine(r);
        Debug.WriteLine(r);
        if (r.ToString() == "")
            break;
    }

    s.Close();

    Console.WriteLine("ok");
}

1 Ответ

0 голосов
/ 30 апреля 2011

TcpClient.GetStream() возвращает NetworkStream, который не поддерживает поиск, поэтому вы не можете изменить указатель считывателя, и до тех пор, пока соединение открыто, оно никогда не заканчивается в конце. Это означает, что метод StreamReader.Peek() может возвращать вводящее в заблуждение -1 при наличии задержки от сервера между ответами.

Один надежный способ получить ответ - установить тайм-аут чтения и просто продолжать цикл до тех пор, пока не будет сгенерировано исключение, которое вы можете перехватить и продолжить. Поток все еще будет доступен для отправки другого сообщения.

       s.ReadTimeout = 1000;

       try
       {
          sw.WriteLine(sendMsg);

          while(true)
          {
            r = sr.ReadLine();
            Console.WriteLine(r);
          } 

         sr.DiscardBufferedData(); 
       }
      catch(IOException)
       {
         //Timed out—probably no more to read
       }


ОБНОВЛЕНИЕ : может также работать следующее, и в этом случае вам не нужно беспокоиться об установке таймаутов или перехвате исключений:
         while(true)
         {
           r = sr.ReadLine();
           Console.WriteLine(r);
           if (sr.Peek() < 0) break;
         } 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...