我有以下服务器应用程序代码:
TcpListener recSock = new TcpListener(400);
recSock.Start();
TcpClient client = recSock.AcceptTcpClient();
NetworkStream netStream = client.GetStream();
Byte[] data = new Byte[256];
int i;
while((i = netStream.Read(data, 0, data.Length)) != 0) {
string cmd = ASCIIEncoding.ASCII.GetString(data, 0, i);
Console.WriteLine(cmd);
if(cmd == "R") {
RestartScheduler();
}
}
client.Close();
客户端看起来像:
TcpClient client = new TcpClient();
client.Connect("VM-SCHEDULER", 400);
NetworkStream netStream = client.GetStream();
Byte[] data = ASCIIEncoding.ASCII.GetBytes("R");
netStream.Write(data, 0, data.Length);
netStream.Flush();
client.Close();
客户端第一次连接时,一切正常,读取“R”命令并调用RestartScheduler()方法,但所有后续命令都会失败,直到服务器重新启动。
我在第一次尝试后使用telnet连接到服务器,它仍在监听端口。
我哪里错了?
编辑:
基本上我要完成的是服务器将始终监听,然后客户端将连接发送“R”命令然后关闭连接。客户端必须能够随时连接到服务器以发出命令。在任何给定时间只有1个客户。
答案 0 :(得分:2)
如果没有要读取的数据,netStream.Read将返回0并且您的while循环将退出,在client.Close();处断开客户端。您的代码中没有任何内容允许服务器在此方案中继续接收。
在应用程序关闭之前,您需要继续侦听连接,因此将listen和GetStream放在while循环中。由于Stream.Read是一个阻塞调用,因此在循环时应该有一些数据用于读取数据(除非发生超时)。否则它将关闭连接并返回收听新的连接。
注意:我在这里没有包含任何错误处理,您需要自己添加。
TcpListener recSock = new TcpListener(400);
recSock.Start();
while (!stopping)
{
TcpClient client = recSock.AcceptTcpClient();
NetworkStream netStream = client.GetStream();
Byte[] data = new Byte[256];
int i = netStream.Read(data, 0, data.Length);
while(i != 0)
{
string cmd = ASCIIEncoding.ASCII.GetString(data, 0, i);
Console.WriteLine(cmd);
if(cmd == "R") {
RestartScheduler();
}
i = stream.Read(bytes, 0, bytes.Length);
}
client.Close();
Thread.Sleep(1); // Will allow the stopping bool to be updated
}
模块级别添加:
private bool stopping = false;
在关机功能中:
stopping = true;
答案 1 :(得分:0)
您是连接多次,还是在同一连接上发送多个命令?如果你能提供一个简短但完整的程序来证明这个问题,那真的会有所帮助。
我的猜测是,由于一次性从单个连接读取多个命令,您遇到了问题,但如果没有更多信息,很难知道。不要忘记,从客户端单次调用Write
很容易导致服务器端的多次读取 - 反之亦然。
答案 2 :(得分:0)
服务器会在收到第一个命令后退出,不是吗?
答案 3 :(得分:0)
至少,您缺少using
语句:
TcpListener recSock = new TcpListener(IPAddress.Loopback, 400);
recSock.Start();
using (TcpClient client = recSock.AcceptTcpClient())
{
using (NetworkStream netStream = client.GetStream())
{
Byte[] data = new Byte[256];
int i;
while ((i = netStream.Read(data, 0, data.Length)) != 0)
{
string cmd = Encoding.ASCII.GetString(data, 0, i);
Console.WriteLine(cmd);
if (cmd == "R")
{
RestartScheduler();
}
}
}
client.Close();
}
和
using (TcpClient client = new TcpClient())
{
client.Connect("VM-SCHEDULER", 400);
using (NetworkStream netStream = client.GetStream())
{
Byte[] data = Encoding.ASCII.GetBytes("R");
netStream.Write(data, 0, data.Length);
netStream.Flush();
}
client.Close();
}