我正在使用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
}
答案 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上排队工作。