Программа зависает, ожидая ввода, который я никогда не смогу дать - PullRequest
0 голосов
/ 27 апреля 2009

Я использую Visual Studio для программирования этого маленького TcpServer.

Это действительно специфично. Сервер прослушивает порт 1234 и находится по IP-адресу 127.0.0.1. Наши преподаватели дали нам программу, которая пытается подключиться к этому порту на том IP, когда вы нажимаете «подключить». Это работает для всех остальных, так что это должно быть ошибка кодирования с моей стороны.

Когда я нажимаю «Подключить», программа отправляет слово «GET» через поток, на который мне нужно ответить списком уже подключенных IP-адресов, а затем новой строкой, содержащей только.

Когда я отключаюсь, программа отправляет слово «REM», и мне просто нужно удалить if из моего списка (который является общим списком)

У меня есть класс TCPServer (мы должны были сделать свой собственный), который имеет этот основной код:

this.tl = new TcpListener(IPAddress.Any, PORT);
tl.Start();
while(true)
{
  TcpClient tcl = tl.AcceptTcpClient();//here the server will wait forever untill someone connects, meaning the "new Thread" statement is never reached untill someone connects.
  TcpHelper th = new TcpHelper(tcl,conf);
  new Thread(new ThreadStart(th.Start)).Start();//should be multi-threaded, not sure if it is.
  //t.Start();
}

TcpHelper выглядит следующим образом (ищите закомментированный текст «вот в чем проблема» в пределах употребления):

public class TcpHelper
{
    private TcpClient tc;
    private IPEndPoint ipe;
    private string get;
    private Configuration conf;

    public TcpHelper(TcpClient tc, Configuration conf)
    {
       this.tc = tc;
       this.conf = conf;
    }

    public void Start()
    {
       using (NetworkStream nws = this.tc.GetStream())
       {
           using (StreamReader sr = new StreamReader(nws))
           {
              using (StreamWriter sw = new StreamWriter(nws))
              {
                  this.ipe = (IPEndPoint)tc.Client.RemoteEndPoint;
                  this.conf.List.Add(this.ipe.Address);
                  bool conn = true;

                  while (conn)
                  {
                      this.get = sr.ReadLine();//here's the problem
                      switch (this.get)
                      {
                          case "GET":
                              foreach (IPAddress address in this.conf.Lijst)
                              {
                                  sw.WriteLine(address.ToString());
                              }
                              sw.WriteLine(".");
                              break;

                          case "REM":
                              this.conf.List.Remove(this.ipe.Address);
                              sw.WriteLine("OK.");
                              conn = false;
                              break;

                          default:
                              break;
                     }
                  }
              }
          }
      }
  }

  #region Properties
  public IPEndPoint Ipe
  {
      get
      {
          return this.ipe;
      }
  }
  #endregion
}

Ответы [ 2 ]

6 голосов
/ 27 апреля 2009

Я предполагаю, что ваша проблема в том, что вы вызываете sr.ReadLine (), но ввод не содержит новой строки, поэтому он заблокирован там в ожидании новой строки.

Вы можете попробовать StreamReader.Read 3 раза, чтобы создать командную строку (GET / REM), прежде чем действовать с ней. (Примечание: 3 раза, потому что все команды состоят из трех символов).

Read вернет целые числа, но после проверки, что они не равны -1 (указывает на конец файла), вы можете привести это целое число к символу.

0 голосов
/ 27 апреля 2009

Извините, может я не понимаю этого ... Вы написали этот код?

this.tl = new TcpListener(IPAddress.Any, PORT);
tl.Start();
while(true)
{
  TcpClient tcl = tl.AcceptTcpClient();
  TcpHelper th = new TcpHelper(tcl,conf);
  new Thread(new ThreadStart(th.Start)).Start();
  //t.Start();
}

Это взорвет **** из любого компьютера. Вы бесконечно зацикливаетесь, создавая новые потоки в каждом цикле. Итак, если вы создаете один новый поток на цикл, и каждый цикл занимает одну миллисекунду (скажем, очень медленно!), Через пять секунд вы получите 5000 потоков. Каждый пытается слушать на одном и том же порту.

Попробуйте использовать один поток. Если это консольное приложение, используйте Console.ReadLine (), чтобы заблокировать основной поток, пока кто-нибудь не нажмет клавишу ввода.


С новой информацией ... AcceptTcpClient блокирует, но вместо создания нового потока работа должна быть поставлена ​​в очередь в ThreadPool.

...