【发布时间】:2021-10-12 11:45:20
【问题描述】:
我有一个像这样工作的“信使”应用程序: 客户端向服务器发送消息 -> 服务器将消息转发给其余客户端 -> 客户端读取消息。
服务器始终接收消息,但客户端不接收。
将消息转发到所有客户端(Server/TcpListener)的代码:
public static void SendToAll(TcpClient sender, string message)
{
// Log the recieved message in the console
Console.WriteLine(message);
// Save the recieved message for new clients
messageLog += message + "\n";
byte[] msg = Encoding.ASCII.GetBytes(message);
foreach (TcpClient client in clients.Keys)
{
if (client == sender || clients[client] == "") continue;
if (!client.Connected)
{
clients.Remove(client);
continue;
}
NetworkStream stream = client.GetStream();
stream.Write(msg, 0, msg.Length);
}
}
从服务器读取消息的代码(TcpClient):
byte[] buffer = new byte[1024];
while (true)
{
using (MemoryStream memoryStream = new MemoryStream())
{
Int32 bytes = 0;
do
{
bytes = stream.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, bytes);
}
while (stream.DataAvailable);
Console.WriteLine(Encoding.ASCII.GetString(memoryStream.ToArray()));
}
【问题讨论】:
-
foreach (TcpClient client in clients.Keys)- 呃,这段代码是否将TcpClient对象存储为字典键?如果是这样,你不应该这样做。 -
我怀疑您的问题是 DataAvailable 返回 false ,因为您的客户端已读取并处理所有可用数据,即使尚未全部到达,并且在准备好之前要求更多,然后在被告知“不可用”时放弃(因为下一个数据仍在传输中)
-
顺便说一句,使用 SignalR 或一些类似的抽象可能会让你的生活更简单
-
@Dai 我只是第一次摆弄 TCP,所以我还没有真正考虑到安全性、性能等。如果您可以选择更好的选择,那就太好了。
-
@CaiusJard 我尝试切换到此代码:
Int32 bytesRead = stream.Read(buffer, 0, buffer.Length); string message = Encoding.ASCII.GetString(buffer, 0, bytesRead); Console.WriteLine(message);还是一样