C# WPF多线程聊天应用服务器端NetworkStream始终无数据可用问题求助
C# WPF多线程聊天应用服务器端NetworkStream始终无数据可用问题求助
你好,我仔细看了你的代码,发现几个关键问题导致服务器端stream.DataAvailable一直返回false,咱们一步步来解决:
1. 服务器端完全没有读取流数据的逻辑
你当前的Server.Communicate方法里,只是循环打印stream.DataAvailable的状态,但从来没有尝试读取流中的数据。哪怕客户端已经发送了数据,服务器不去主动读取的话,不仅无法拿到消息,还可能导致流状态异常。
而且DataAvailable只是一个瞬时状态——如果在你检查的瞬间数据还没传输到,就会返回false,但之后数据到达了,你要等10秒才会再次检查,这完全错过了接收时机。
修复方案:在循环中加入读取逻辑,并且和客户端保持一致的编码(你客户端用的是UnicodeEncoding.Unicode,也就是UTF-16):
public void Communicate(TcpListener listener) { String data; listener.Start(); Debug.WriteLine("start Connecting to Client"); client = listener.AcceptTcpClient(); Debug.WriteLine("Connected to Client"); if (client != null) { Debug.WriteLine("client is valid"); NetworkStream stream = client.GetStream(); byte[] buffer = new byte[client.ReceiveBufferSize]; int bytesRead; // Read方法是阻塞的,会一直等待直到有数据可读或连接关闭 while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0) { string receivedMsg = UnicodeEncoding.Unicode.GetString(buffer, 0, bytesRead); Debug.WriteLine($"收到客户端消息:{receivedMsg}"); Debug.WriteLine($"当前DataAvailable状态:{stream.DataAvailable}"); } // 连接关闭后清理资源 client.Close(); listener.Stop(); } }
2. 客户端发送数据后未强制刷新缓冲区
客户端发送数据时,.NET可能会把数据暂时存在缓冲区里,没有立即发送到网络。你可以在发送后调用Flush()强制清空缓冲区,确保数据立即传输:
public void Communicate(TcpClient client, String message, System.Windows.Controls.Label messagebox) { Debug.WriteLine("start Communication"); NetworkStream stream = client.GetStream(); byte[] message_byte = UnicodeEncoding.Unicode.GetBytes(message); stream.Write(message_byte, 0, message_byte.Length); stream.Flush(); // 强制发送缓冲区数据 // 这里的inputData数组没用到,可以删掉或者补充接收服务器响应的逻辑 // byte[] inputData = new Byte[client.ReceiveBufferSize]; // 注意:WPF控件不能跨线程直接修改,这里要加Dispatcher messagebox.Dispatcher.Invoke(() => { messagebox.Content = messagebox.Content + "\n" + "message is sent"; }); }
3. 额外提醒:WPF跨线程UI访问问题
你现在在客户端的Communicate方法里直接修改Label的Content,这会触发跨线程访问UI控件异常——WPF的UI元素只能在主线程操作。上面的代码已经帮你加上了Dispatcher.Invoke来处理这个问题,服务器端如果之后要更新UI,也要用同样的方式。
按照上面的修改,你应该能看到服务器端成功接收到消息,stream.DataAvailable也会在数据到达时正确返回true。
备注:内容来源于stack exchange,提问作者Lisa




