C#TCP客户端在侦听服务器和更新GUI时遇到问题

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

我有一个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\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错误