C#TCP客户端在侦听服务器和更新GUI时遇到问题
我有一个GUI,有两个按钮和一个文本框。Button1启动服务器并让它侦听客户端。按钮2向服务器发送连接请求,并开始侦听服务器将发送给客户端的任何内容(响应)。虽然在服务器发送回复时使用了我的当前代码,并且我尝试将其写入文本框,但整个系统挂起 代码如下所示: 服务器类:C#TCP客户端在侦听服务器和更新GUI时遇到问题,c#,visual-studio-2010,tcp,tcplistener,C#,Visual Studio 2010,Tcp,Tcplistener,我有一个GUI,有两个按钮和一个文本框。Button1启动服务器并让它侦听客户端。按钮2向服务器发送连接请求,并开始侦听服务器将发送给客户端的任何内容(响应)。虽然在服务器发送回复时使用了我的当前代码,并且我尝试将其写入文本框,但整个系统挂起 代码如下所示: 服务器类: class Server { private TcpListener tcpListener; private Thread listenThread; private void ListenForC
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\u Click(object sender,EventArgs e)
调用tb\u received.Text=encoder.GetString(message,0,bytesRead)的代码行时代码>程序挂起,因为您在UI线程上运行的EthStartB\u单击中有while(true)
循环clientStream.Read
调用将阻止UI线程
在新线程上移动接收逻辑,并使用控件设置文本框
内容。调用
或Dipatcher。调用
取决于您是在WinForms上还是在WPF上,并且仅当您在消息
中确实有一些内容要写入文本框时才这样做
还有另一个问题,因为在服务器上执行循环时,tcpClient.Close()
在外部,所以客户端和服务器都不会断开连接。两者都将阻塞各自的流。读取调用
由于您在同一台计算机上同时运行客户端和服务器,因此不需要使用TcpListener-ClientListener
,也不会与已在同一端口上侦听的服务器配合使用。这是WinForms还是WPF?更新GUI的命令需要出现在UI线程中,否则会引发跨线程异常,你的代码可能是什么?我可以使用Control.Invoke来避免这种情况是吗?@Aydinand这是WinForms为什么?(很抱歉反应太晚。正在忙于不同的项目)@DarthSheldon,YK1一针见血,所以引用他的话。。。“在新线程上移动接收逻辑,并使用Control.Invoke或Dipatcher.Invoke设置textbox内容,具体取决于您是在WinForms上还是在WPF上,并且只有在消息中有一些内容要写入textbox时才执行此操作。”我问这个问题,因为这会影响您如何返回UI线程:)抱歉,响应太晚,上星期我被安排到另一个项目。我之所以有监听器,是因为这个服务器只是为了测试客户机代码而安装的。服务器代码将在实际项目中的微控制器中。我只是想让TCP工作,这样服务器就可以先发送/接收w/o错误