C# TCP客户端-数据仅在某些部分损坏

C# TCP客户端-数据仅在某些部分损坏,c#,tcpclient,C#,Tcpclient,我有一个向服务器发送文件的客户端应用程序。问题是,在客户端部分,文件被正确读取,我可以在读取字节数组并将其保存为有效的jpg后再次保存它。然而,在服务器端,数据在某些地方被破坏。我所做的就是不断地将所有传入数据添加到列表中,直到客户端关闭连接 我将发送/接收的客户端和服务器数据重叠,正如您所看到的,有些地方的数据不匹配: 我不明白这是怎么可能的,我使用的是一个大的缓冲区,而且图像相当小,所以即使服务器在一个“块”中接收到图像,数据仍然损坏 知道为什么会这样吗 更新: 客户端: 我正在使用Http

我有一个向服务器发送文件的客户端应用程序。问题是,在客户端部分,文件被正确读取,我可以在读取字节数组并将其保存为有效的jpg后再次保存它。然而,在服务器端,数据在某些地方被破坏。我所做的就是不断地将所有传入数据添加到列表中,直到客户端关闭连接

我将发送/接收的客户端和服务器数据重叠,正如您所看到的,有些地方的数据不匹配:

我不明白这是怎么可能的,我使用的是一个大的缓冲区,而且图像相当小,所以即使服务器在一个“块”中接收到图像,数据仍然损坏

知道为什么会这样吗

更新:

客户端:

我正在使用HttpWebRequest获取图像:

                  List<byte> test_buffer = new List<byte>();

                  using (Stream MyResponseStream = hwresponse.GetResponseStream())
                  {
                      byte[] MyBuffer = new byte[4096];
                      int BytesRead;

                      while (0 < (BytesRead = MyResponseStream.Read(MyBuffer, 0, MyBuffer.Length)))
                      {

                          for (int i = 0; i < BytesRead; i++)
                          {
                              test_buffer.Add(MyBuffer[i]); // just for testing
                          }

                          TCP_R.SendBytes(MyBuffer); // send data back to server
                      }
                  }

                  TCP_R.Close(); // tell server that we're done sending data
注意,我使用test_buffer收集所有字节,以验证是否正确接收了所有内容。如果我使用此代码:

                  MemoryStream ms = new MemoryStream(test_buffer.ToArray());
                  Image returnImage = Image.FromStream(ms);
                  returnImage.Save("image.jpg");
图像已成功创建。所以我假设客户机正确地发送数据

服务器端:

我使用OnDataReceived函数收集数据,并在请求\u响应中构建所有数据,即
列表

如何在不使用解码器的情况下将数据提取到socketData.dataBuffer中

解决方案: 尽管我直接从dataBuffer读取数据,“d.GetChars(socketData.dataBuffer..”行不知怎么搞砸了缓冲区,因此我得到了错误的数据。我仍然需要使用GetChars将数据包的第一部分读取为字符串,所以我只是更改了:

 int charLen = d.GetChars(socketData.dataBuffer, 0, iRx, chars, 0);
致:


现在一切都很顺利。显然,直接在缓冲区上调用getChars会影响缓冲区。

听起来像是编码问题

这里的关键概念是编码用于文本,而图像不是文本

在发送之前或接收之后,不要尝试对字节进行编码或解码

同样,如果从文件中读取或写入图像,不要尝试编码或解码,请使用二进制模式


只是不要尝试将字节转换为字符,这样做没有意义。

给我们看一些代码。如果你遗漏了所有细节,你就不能指望我们回答这个问题。我怀疑你的代码中有错误,无论是在客户端还是服务器上。不幸的是,你既没有向我们展示客户端代码,也没有向我们展示服务器代码,这使得很难说…需要查看您的代码…发送和接收。我们需要查看执行接收的代码,特别是读/接收循环,以及它如何处理读/接收的返回值,以及它在哪里处理计数/偏移。如果这些听起来都不熟悉,那么肯定是问题所在。@user1192403“我怎么能?"问题:这就是Receive所做的。GetChars读取缓冲区,这纯粹是推测。特别是,通过tcp发送原始二进制数据不应该涉及任何编码。这个问题除了推测之外,不应该涉及任何编码。是的,它不应该涉及任何编码,这就是我认为编码可能是问题的原因。Samuel,我想你是对的。你能检查一下我的服务器端代码吗,我在里面有UTF8,我怎么能不使用UTF8编码就提取缓冲区中的所有字节!?@user1192403你到底为什么要使用文本处理?Jpg不是文本数据。你应该只使用原始字节[]来处理这个问题。根本没有“char”。
  public void OnDataReceived(IAsyncResult asyn)
    {

        try
        {
            SocketPacket socketData = (SocketPacket)asyn.AsyncState; // cast

            int iRx = 0;

                iRx = socketData.m_currentSocket.EndReceive(asyn);
                char[] chars = new char[iRx + 1];

                System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder(); // CAN THIS BE CAUSING THE PROBLEM!?!
                int charLen = d.GetChars(socketData.dataBuffer, 0, iRx, chars, 0);


                for (int s = 0; s < charLen; s++)
                {

                    RESPONSE_DATA.Add(socketData.dataBuffer[s]); // Collect response data

                }

                WaitForData(socketData.m_currentSocket, socketData.socket_id, REQUEST_INDEX_ID);

            }

        }
        catch (ObjectDisposedException)
        {

        }
        catch (SocketException se)
        {

        }
    }
                System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder(); // CAN THIS BE CAUSING THE PROBLEM!?!
                int charLen = d.GetChars(socketData.dataBuffer, 0, iRx, chars, 0);
 int charLen = d.GetChars(socketData.dataBuffer, 0, iRx, chars, 0);
 byte[] tmp_a = new byte[socketData.dataBuffer.Length];
 tmp_a = socketData.dataBuffer;
 int charLen = d.GetChars(tmp_a, 0, iRx, chars, 0);