以下源代码轮询传入的客户端连接。
class ServerForm : Form
{
//...
void PollIncomingClientConns(TcpListener listener)
{
listener.Start();
_keepPolling = true;
try
{
while (_keepPolling)
{
ClientClass client = new ClientClass(listener);
ClientDictionary.Add(client.ID, client);
SetStringToTextBox("Client [" + client.ID + "] is now connected.");
Thread thread = new Thread(delegate()
{
ReadFromClient(client);
});
thread.IsBackground = true;
thread.Start();
}
_tcplistener.Server.Close();
_tcplistener.Server.Dispose();
_tcplistener = null;
}
catch (Exception ex)
{
var inner = ex.InnerException as SocketException;
if (inner != null && inner.SocketErrorCode == SocketError.ConnectionReset)
{
SetStringToTextBox("Disconnected");
}
else
{
SetStringToTextBox(ex.Message);
}
listener.Stop();
}
}
void ReadFromClient(ClientClass client)
{
try
{
while (true)
{
string str = client.Read();
SetStringToTextBox("[" + client.ID + "] says: " + str);
switch (str)
{
// ... service client requests ...
// ... text messages ...
}
if (!client.Tcp.Connected)
{
SetStringToTextBox("[" + client.ID + "] is disconnected.");
client.Close();
break;
}
}
}
catch
{
client.Close();
}
}
// ...
}
为了关闭服务器,我单击了一个按钮,并将_keepPolling
设置为false。
但是,在客户端,我发现客户端仍然能够连接到服务器。即服务器没有关闭。
如何解决此问题?
相关源代码
以下是客户端源代码,
public class ClientClass
{
public string ID { get; private set; }
public string Host { get; set; }
public int Port { get; set; }
public TcpClient Tcp { get; private set; }
private BinaryReader reader;
private BinaryWriter writer;
/// <summary>
/// Creates a clienbt at the Client-end.
/// This requires Host and Post property to be set.
/// </summary>
public ClientClass()
{
Random rnd = new Random();
ID = AlphaNumRandom.GenerateUpperCaseString(5, rnd);
}
/// <summary>
/// Creates a client at the Client-end.
/// </summary>
/// <param name="host"></param>
/// <param name="port"></param>
public ClientClass(string host, int port)
{
Random rnd = new Random();
ID = AlphaNumRandom.GenerateUpperCaseString(5, rnd);
Host = host;
Port = port;
}
/// <summary>
/// creates a proxy-client at the Server-end.
/// </summary>
/// <param name="listener"></param>
public ClientClass(TcpListener listener)
{
Tcp = listener.AcceptTcpClient();
Host = ((IPEndPoint)Tcp.Client.RemoteEndPoint).Address.ToString();
Port = ((IPEndPoint)Tcp.Client.LocalEndPoint).Port;
NetworkStream stream = Tcp.GetStream();
reader = new BinaryReader(stream);
writer = new BinaryWriter(stream);
ID = Read();
}
/// <summary>
/// Connects the client to the server.
/// </summary>
/// <returns></returns>
public bool Connect()
{
bool is_connected = IsConnected();
if (!is_connected)
{
Tcp = new TcpClient(Host, Port);
NetworkStream stream = Tcp.GetStream();
reader = new BinaryReader(stream);
writer = new BinaryWriter(stream);
return true;
}
else if (is_connected)
{
return true;
}
else 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 " + ID + " 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 " + ID + " is not connected!");
}
}
public void PrintID()
{
Console.WriteLine("Client ID = {0}", ID);
}
public void SendIdToServer()
{
this.Write(ID);
}
public bool Close()
{
if (IsConnected())
{
if (Tcp != null)
{
Tcp.Close();
Tcp = null;
return true;
}
}
return false;
}
}
编辑:
class ServerForm : Form
{
// ...
private void startToolStripMenuItem_Click(object sender, EventArgs e)
{
string ipAddress = Constants.LOCAL_HOST_IP;
int portNo = Constants.PORT_NO;
IPAddress ip = IPAddress.Parse(ipAddress);
_tcplistener = new TcpListener(ip, portNo);
// poll for clients in a 2nd thread
Thread thread = new Thread(delegate()
{
PollIncomingClientConns(_tcplistener);
});
thread.IsBackground = true;
thread.Start();
SetStringToTextBox("Server program started on address [" + ipAddress + ":" + portNo + "]");
startToolStripMenuItem.Enabled = false;
stopToolStripMenuItem.Enabled = true;
}
// ...
}
答案 0 :(得分:0)
经过一些测试,只需调用_tcplistener.Stop();
就可以了。在将_keepPolling
设置为false的地方调用它