TcpListener正在随机截断字节数组

本文关键字:字节 字节数 数组 随机 TcpListener | 更新日期: 2023-09-27 18:27:34

我正在编写一个本质上是用于存储图像的图像备份服务器。它是一种单向服务,除了基本的成功或失败消息之外,不会向客户端返回任何信息。

我遇到的问题是,当我通过网络流发送字节数组时,它在流结束前的随机位置被截断。当我在开发机器上运行服务器并进行本地连接时,我没有这个问题,但只有当服务器部署在远程服务器上时才会出现这个问题。

当我发送非常小的数组(<512字节)时,服务器会成功接收整个流,但在大于2000字节的流上,我会遇到问题。客户端的代码如下:

    try
    {
        TcpClient Voice = new System.Net.Sockets.TcpClient();
        //Obviously I use the remote IP when it is deployed - but have altered it for privacy.
        IPEndPoint BackupServer = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 57000);
        Voice.Connect(BackupServer);
        NetworkStream DataStream = Voice.GetStream();
        byte[] buffer = new ASCIIEncoding().GetBytes(ImageData.GetXml());
        DataStream.Write(buffer, 0, buffer.Length);
        DataStream.Flush();
      }
      catch 
      {
      }
      try
      {
        buffer = new byte[4096];
        int read = DataStream.Read(buffer, 0, buffer.Length);
        MessageBox.Show(new ASCIIEncoding().GetString(buffer) + " : " + read.ToString());
      }
      catch
      {
      }

无论我发送的数据大小如何,客户端代码都不会出现任何错误或问题。

服务器端的代码如下:

  private void BackMeUp(object voice)
  {
    TcpClient Voice = (TcpClient)voice;
    Voice.ReceiveTimeout = 30000;
    NetworkStream DataStream = Voice.GetStream();
    try
    {            
      bool ShouldLoop = true;
      //int loops = 0;
      int loops = -1;
      byte[] input = new byte[2048];
      byte[] buffer = new byte[0];
      //while (ShouldLoop)
      while(loops != 0)
      {
        loops = DataStream.Read(input, 0, 2048);
        for (int x = 0; x < loops; x++)
        {                        
          Array.Resize(ref buffer, buffer.Length + 1);
          buffer[buffer.Length - 1] = input[x];                       
        }
        //if (loops < 2048)
        //{
          //ShouldLoop = false;
          //break;
        //}                    
      }
      while (true)
      {   
        StringReader Reader = new StringReader(new ASCIIEncoding().GetString(buffer, 0, buffer.Length));
        DataSet DS = new DataSet();
        DS.ReadXml(Reader);
        if (DS.Tables.Count > 0)
        {
          if (DS.Tables["Images"].Rows.Count > 0)
          {
            foreach (DataRow row in DS.Tables["Images"].Rows)
            {
                  //
            }
          }
        }
        string response = "Got it!";                    
        DataStream.Write(new ASCIIEncoding().GetBytes(response), 0, response.Length);
        DataStream.Flush();
        Voice.Close();
        break;                  
      }
    }
    catch (Exception Ex)
    {
      File.WriteAllText("Elog.txt", Ex.Message + " " + (Ex.InnerException != null ? Ex.InnerException.ToString() : " no Inner"));
      Voice.Close();
    }
  }

服务器会很好地接收数据,并在数据流到达末尾时关闭数据流,但是数据被截断,并且在尝试重建数据集时出错。

我觉得这与发送流所需的时间有关,我也玩过Close和Flush命令,但我觉得我只是在黑暗中拍摄。如有任何帮助,我们将不胜感激。

问题的简明版本:TcpListener涉及哪些因素,可能导致a)流的截断。或b)在读取所有字节之前过早地关闭流。当有问题的侦听器位于远程主机而不是本地服务器上时。

TcpListener正在随机截断字节数组

Read方法不必同时返回请求的字节数或整个流。特别是如果流很慢,它将以小块的形式返回。

重复调用Read方法,并处理您获得的每个块的数据。当流被读取到最后时,Read方法返回零:

buffer = new byte[4096];
do {
  int read = DataStream.Read(buffer, 0, buffer.Length);
  if (read != 0) {
    // handle the first "read" bytes of the buffer (index 0 to read-1)
  }
} while (read != 0);

如果你知道你的缓冲区足以容纳任何流,你可以填满缓冲区,然后再处理:

buffer = new byte[4096];
int offset = 0;
do {
  int read = DataStream.Read(buffer, offset, buffer.Length - offset);
  offset += read;
} while (read != 0);
// handle the first "offset" bytes of the buffer (index 0 to offset-1)