程序挂起,等待我永远不会给出的输入

时间:2009-04-27 12:28:09

标签: c# visual-studio tcplistener

我正在使用visual studio来编写这个小型TcpServer。

这是非常具体的。服务器侦听端口1234,位于IP 127.0.0.1上 我们的老师给了我们一个程序,当你点击“连接”时,该程序试图连接到该IP上的那个端口。它适用于其他所有人,因此我必须是编码错误。

当我点击连接时,程序会在流上发送“GET”字样,我必须对所有已连接的IP地址列表进行响应,然后是仅包含a的新行。

当我断开连接时,程序发送单词“REM”,我只需要从我的列表中删除(这是一个通用列表)

我有一个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 个答案:

答案 0 :(得分:6)

我的猜测是你的问题是你正在调用sr.ReadLine(),但是输入不包含换行符,所以它在那里被阻塞,等待永远不会出现的换行符。

您可能需要尝试调用StreamReader.Read 3次以构建命令字符串(GET / REM),然后再对其进行操作。 (注意:3次是因为所有命令都是三个字符)。

Read将返回整数,但在检查它们不是-1(表示文件结尾)后,可以将该整数转换为char。

答案 1 :(得分:0)

对不起,也许我不明白这个......你写的这段代码了吗?

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();
}

这将打破任何电脑的****。你无限循环,在每个循环上创建新线程。所以,如果你为每个循环创建一个新线程,并且每个循环花费一毫秒(假设它非常慢!),在五秒钟内你就有了5,000个线程。每个人都试图在同一个港口听。

尝试使用单个线程。如果这是一个控制台应用程序,使用Console.ReadLine()来阻止主线程,直到有人按下回车键。


使用新信息... AcceptTcpClient阻止,但不是创建新线程,而是应该在ThreadPool上排队工作。