我已经使用线程和套接字为服务器和多个客户端编写了代码。通常客户端通过向服务器发送'exit'关键字退出,但我希望服务器也检测客户端强制退出而不向服务器发送'exit'关键字时的情况,例如当用户在向服务器发送消息中间按下交叉按钮时客户端窗口。我想要的是服务器应该检测到这种情况并显示一些错误代码并继续从连接到它的其他客户端接收消息。
我面临的第二个问题即使有多个客户端连接到服务器,我也如何断开服务器。在我的代码中,我使用的是 tcpListener.Stop(),但是当我使用此方法时,会显示错误消息“服务器无法在 ipaddress 启动”,并且此类窗口打开的数量等于服务器正在侦听的客户端数量。例如,如果服务器正在监听 1000 个客户端,则将打开 1000 个这样的窗口,显示前面提到的错误消息,从使用该软件的人的角度来看,这看起来不太好。那么我该如何处理这种情况呢?同样在这种情况下,如果客户端再次开始向服务器发送消息,那么即使我已断开服务器连接,也会开始接收消息。服务器应保持断开连接,直到用户重新启动服务器。
以下是我的服务器代码。
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
// Constants IP address of server and maximum number of clients server can connect.
static class Constants
{
public const string IP = "127.0.0.1";
public const int No_Of_Clients = 2;
}
// server port number
int port_number;
static IPAddress ipAddress = IPAddress.Parse(Constants.IP);
TcpListener tcpListener;
public Form1()
{
InitializeComponent();
button1.Click += button1_Click;
button2.Click += button2_Click;
//this.FormClosing += Form1_FormClosing;
}
//Socket socketForClient;
private void button1_Click(object sender, EventArgs e)
{
if (String.IsNullOrEmpty(textBox1.Text.Trim()))
{
System.Windows.Forms.MessageBox.Show("Port Number Empty", "Error");
}
else
{
port_number = int.Parse(textBox1.Text);
createserver(Constants.No_Of_Clients);
serveripaddress();
infoBox1.Text = string.Format("The server is now listening at port {0} at ip address {1}", port_number, Constants.IP);
infoBox1.Text = infoBox1.Text + "\r\n" + string.Format("The server can listen to maximum {0} number of clients", Constants.No_Of_Clients);
}
}
// this code disconnects the server
private void button2_Click(object sender, EventArgs e)
{
try
{
tcpListener.Stop();
}
catch (Exception f)
{
MessageBox.Show(f.Message);
}
}
public void serveripaddress()
{
serverip.Text = "Server IP : " + Constants.IP;
//serverport.Text = "Port Number : " + port.ToString();
}
// Starts server
private void createserver(int no_of_clients)
{
tcpListener = new TcpListener(ipAddress, port_number);
tcpListener.Start();
for (int i = 0; i < no_of_clients; i++)
{
Thread newThread = new Thread(new ThreadStart(Listeners));
newThread.Start();
}
} // end of createserver();
//listen to client receiving messages
public void Listeners()
{
Socket socketForClient;
try
{
socketForClient = tcpListener.AcceptSocket();
}
catch
{
System.Windows.Forms.MessageBox.Show(string.Format("Server failed to start at {0}:{1}", Constants.IP, port_number), "Error");
return;
}
if (socketForClient.Connected)
{
//System.Windows.Forms.MessageBox.Show("hello");
string string1 = string.Format("Client : " + socketForClient.RemoteEndPoint + " is now connected to server.");
infoBox1.Text = infoBox1.Text + "\r\n" + string1;
NetworkStream networkStream = new NetworkStream(socketForClient);
System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(networkStream);
System.IO.StreamReader streamReader = new System.IO.StreamReader(networkStream);
string theString = "";
while (true)
{
try
{
theString = streamReader.ReadLine();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
// if (streamReader.ReadLine() == null )
//{
// System.Windows.Forms.MessageBox.Show(string.Format("Server failed to start at {0}:{1}", Constants.IP, port_number), "Error");
// }
if (theString != "exit")
{
textBox2.Text = textBox2.Text + "\r\n" + "-----------------------------------------------------------------------------------";
string string2 = string.Format("Message recieved from client(" + socketForClient.RemoteEndPoint + ") : " + theString);
textBox2.Text = textBox2.Text + "\r\n" + string2;
// ASCII code for the message from client
string string3 = string.Format("ASCII Code for message is : ");
textBox2.Text = textBox2.Text + "\r\n" + string3;
string string4 = "";
foreach (char c in theString)
{
string4 += string.Format(System.Convert.ToInt32(c) + " ");
}
textBox2.Text = textBox2.Text + string4;
// Hex value of message from client
string hex = "";
foreach (char c in theString)
{
int tmp = c;
hex += String.Format("{0:x2}", (uint)System.Convert.ToUInt32(tmp.ToString()));
}
string string5 = string.Format("Hex Code for the message from client : " + hex);
textBox2.Text = textBox2.Text + "\r\n" + string5;
//sending acknowledgement to client
try
{
socketForClient.Send(new ASCIIEncoding().GetBytes("The string was recieved from Client(" + socketForClient.RemoteEndPoint + ") : " + theString));
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
} // end of if loop
// if exit from client
else
{
string string7 = string.Format("Client " + socketForClient.RemoteEndPoint + " has exited");
infoBox1.Text = infoBox1.Text + "\r\n" + string7;
break;
}
} // end of while loop
streamReader.Close();
networkStream.Close();
streamWriter.Close();
} // end of if loop
socketForClient.Close();
}
}
}