我的服务器应用程序具有以下源代码:
public class ServerClass
{
private TcpListener listener;
private List<ClientClass> clientProxyList;
private int clientCount = -99;
public string IpAddress { get; set; }
public int PortNo { get; set; }
private bool is_started;
private Thread clientPollingThread;
public ServerClass()
{
clientProxyList = new List<ClientClass>();
clientCount = 0;
is_started = false;
}
public ServerClass(string ipAddress, int portNo)
{
IpAddress = ipAddress;
PortNo = portNo;
clientProxyList = new List<ClientClass>();
clientCount = 0;
is_started = false;
}
private void PollForSingleClients()
{
while (listener.Server.Connected)
{
string str = clientProxyList[0].Read();
Console.WriteLine("client says: " + str);
}
}
private void PollForMultipleClients()
{
while (listener.Server.Connected)
{
ClientProxy item = new ClientProxy(listener);
clientProxyList.Add(item);
while (listener.Server.Connected)
{
foreach (ClientClass cc in clientProxyList)
{
string str = cc.Read();
Console.WriteLine("client says: " + str);
}
}
}
}
public void StartForSingleClient()
{
is_started = true;
IPAddress ip = IPAddress.Parse(IpAddress);
listener = new TcpListener(ip, PortNo);
listener.Start();
ClientProxy item = new ClientProxy(listener);
clientProxyList.Add(item);
//seperate thread is needed because of 2 reasons:
// 1. if the server craches, the main thread is not closed.
// 2. the function deosn't return until the while loop ends.
clientPollingThread = new Thread(delegate ()
{
PollForSingleClients();
});
clientPollingThread.Start();
}
public void StartForMultipleClient()
{
is_started = true;
IPAddress ip = IPAddress.Parse(IpAddress);
listener = new TcpListener(ip, PortNo);
listener.Start();
//seperate thread is needed because of 2 reasons:
// 1. if the server craches, the main thread is not closed.
// 2. the function deosn't return until the while loop ends.
clientPollingThread = new Thread(delegate ()
{
PollForMultipleClients();
});
clientPollingThread.Start();
}
public void Stop()
{
foreach (ClientClass cc in clientProxyList)
{
cc.Disconnect();
}
clientProxyList.Clear();
listener.Stop();
listener = null;
is_started = false;
}
public bool IsActive()
{
if (is_started == false)
{
return false;
}
if (listener == null)
{
return false;
}
if (listener.Server == null)
{
return false;
}
return true;
}
}
此代码给我带来的麻烦是,一旦通过调用StartForSingleClient()
启动服务器,它就不会停止(因为在下面的代码中,ClientClass.IsServerActive()
总是返回 { {1}} )。
我既无法在任务管理器中看到它,也无法启动新服务器,也无法将客户端连接到已经运行的 ghost 服务器。
如何摆脱这个问题?
相关源代码
ClientClass.cs
true
ClientProxy.cs
public class ClientClass
{
public string Host { get; set; }
public int Port { get; set; }
public TcpClient Tcp { get; protected set; }
protected BinaryReader reader;
protected BinaryWriter writer;
/// <summary>
/// Creates a clienbt at the Client-end.
/// This requires Host and Post property to be set.
/// </summary>
public ClientClass()
{
}
/// <summary>
/// Creates a client at the Client-end.
/// </summary>
/// <param name="host"></param>
/// <param name="port"></param>
public ClientClass(string host, int port)
{
Host = host;
Port = port;
}
/// <summary>
/// Connects the client to the server.
/// </summary>
/// <returns></returns>
public bool Connect()
{
bool is_connected = IsConnected();
if (is_connected)
{
return true;
}
if (!is_connected)
{
try
{
Tcp = new TcpClient(Host, Port);
NetworkStream stream = Tcp.GetStream();
reader = new BinaryReader(stream);
writer = new BinaryWriter(stream);
return true;
}
catch
{
return false;
}
}
return false;
}
public bool IsConnected()
{
if (Tcp == null)
{
return false;
}
else
{
Socket s = Tcp.Client;
bool part1 = s.Poll(1000, SelectMode.SelectRead);
bool part2 = (s.Available == 0);
if ((part1 && part2) || !s.Connected)
return false;
else
return true;
}
}
public void Write(string str)
{
if (IsConnected())
{
byte[] strBytes = Encoding.UTF8.GetBytes(str);
byte[] lenBytes = BitConverter.GetBytes(strBytes.Length);
Array.Reverse(lenBytes);
writer.Write(lenBytes);
writer.Write(strBytes);
writer.Flush();
}
else
{
throw new Exception("Client is not connected!");
}
}
public string Read()
{
if (IsConnected())
{
byte[] lenBytes = reader.ReadBytes(4);
Array.Reverse(lenBytes);
int len = BitConverter.ToInt32(lenBytes, 0);
byte[] bytes = reader.ReadBytes(len);
string str = Encoding.UTF8.GetString(bytes);
return str;
}
else
{
throw new Exception("Client is not connected!");
}
}
public bool Disconnect()
{
if (IsConnected())
{
if (Tcp != null)
{
Tcp.Close();
Tcp = null;
return true;
}
}
return false;
}
public bool IsServerActive()
{
bool returns = false;
try
{
Connect();
returns = true;
}
catch
{
}
Disconnect();
return returns;
}
}