我有一个带有2个按钮和一个文本框的GUI。 Button1启动服务器并让它监听客户端。按钮2向服务器发送连接请求,并开始侦听服务器将发送给客户端的任何内容(响应)。虽然我在服务器发送回复时使用当前代码,但我尝试将其写入文本框,整个系统都会挂起。
代码如下所示: 服务器类:
class Server
{
private TcpListener tcpListener;
private Thread listenThread;
private void ListenForClients()
{
this.tcpListener.Start();
while (true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
//create a thread to handle communication
//with connected client
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead;
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
catch
{
//a socket error has occured
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
//message has successfully been received
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] buffer = encoder.GetBytes("Hello Client!");
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
}
tcpClient.Close();
}
public Server()
{
this.tcpListener = new TcpListener(IPAddress.Any, 3000);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
}
GUI类:
private void buttonServerStart_Click(object sender, EventArgs e)
{
Server Myserver = new Server();
}
//Greet the Server and listen for response...
private void EthStartB_Click(object sender, EventArgs e)
{
TcpClient client = new TcpClient();
byte[] message = new byte[4096];
int bytesRead;
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3000);
client.Connect(serverEndPoint);
NetworkStream clientStream = client.GetStream();
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] buffer = encoder.GetBytes("Hello Server!");
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
//start listening
this.ClientListener.Start();
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
catch
{
//a socket error has occured
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
//message has successfully been received
tb_recieved.Clear();
tb_recieved.Text=encoder.GetString(message,0,bytesRead);
}
}
TcpListener ClientListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 3000);
private void EthEndB_Click(object sender, EventArgs e)
{
Form3 frmT = new Form3();
frmT.Show();
}
}
问题是private void EthStartB_Click(object sender, EventArgs e)
调用tb_recieved.Text=encoder.GetString(message,0,bytesRead);
答案 0 :(得分:2)
程序挂起,因为while(true)
中的EthStartB_Click
循环在UI线程上运行。 clientStream.Read
调用将阻止UI线程。
在新线程上移动接收逻辑,并使用textbox
或Control.Invoke
设置Dipatcher.Invoke
内容,具体取决于您是使用WinForms还是WPF - 并且仅在您确实拥有时才这样做message
中的一些内容要写入文本框。
还有另一个问题,因为服务器上有tcpClient.Close()
外部 while
循环,客户端和服务器都不会断开连接。两者都会阻止他们各自的stream.Read
来电。
由于您在同一台计算机上同时运行客户端和服务器,因此不需要TcpListener ClientListener
,并且对于已在同一端口上侦听的服务器将无法正常运行。