【问题标题】:TcpClient doesn't reveive all dataTcpClient 不会接收所有数据
【发布时间】: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()));
}

Server (image attached)

Client1 (image attached)

Client2 (image attached)

【问题讨论】:

  • 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); 还是一样

标签: c# .net tcp tcpclient


【解决方案1】:

找到答案了。

问题可能是因为 TCP 速度慢;读取所有流还没有完全完成,并且已经负责读取新数据。

所以我换了

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()));
}

// ... Main() {
while (true) StartRead();
// ... }

public static async void StartRead(NetworkStream stream)
{
    byte[] buffer = new byte[1024];
    Int32 bytesRead = await stream.ReadAsync(buffer.AsMemory(0, buffer.Length));
    string message = Encoding.ASCII.GetString(buffer, 0, bytesRead);
    Console.WriteLine(message);         
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-03
    • 1970-01-01
    • 2012-10-19
    • 1970-01-01
    • 2013-09-09
    • 2014-01-16
    • 2016-07-04
    • 2017-05-10
    相关资源
    最近更新 更多