为什么 TCP 客户端不发送所有字节?

Why does TCP client not send all bytes?

我在 Raspbian 上通过本地主机使用 TCP 套接字在我的 C#/Mono 程序和 Python 脚本之间传递数据。数据约为 64k 字节。问题是并非所有字节都已发送。发送的最大字节数是 49152。我希望它们在一个数据包中到达。

我的代码:

tcpListener = new TcpListener(ip, port);
tcpListener.Start();
tcpClient = tcpListener.AcceptTcpClient();
tcpClient.SendBufferSize = 1000000;
tcpClient.ReceiveBufferSize = 1000000;
networkStream = tcpClient.GetStream();

我试过以下两种写数据的方法,都没有发送完所有字节。

tcpClient.Client.Send(byteArray, byteArray.Length, SocketFlags.None);
// OR            
while (!networkStream.CanWrite)
{
     Thread.Sleep(50);
}
networkStream.Write(byteArray, 0, size);

目前我使用连续两次传输将数据发送到脚本。

这是单声道错误吗?还是我做错了什么?

我以前遇到过这个问题。 基本上,您需要考虑网络操作的实际工作方式。

当你

networkStream.Write(byteArray, 0, size);

是的,您正在将其写入流,但流需要保持打开状态,直到客户端完成接收数据。

在我的例子中——我正在发送数据,然后假设 networkStream.Read 操作已经完成,然后关闭 'Write' 端的连接。

如果执行写入的客户端关闭连接,在他们 'think' 写入 file/data 之后,但在接收方实际 'read' 数据之前,您可以 运行 部分数据丢失的实例。

解决这个问题的方法是创建一个网络协议。

一种常见的策略是测量您希望发送的数据量,然后将其作为长变量在有效负载之前发送。 然后接收方将知道预期有多少数据并将从流中读取该数量的数据。 完成后,接收方应让客户端知道他们已收到所有数据。

写入客户端可以'waiting'为此确认消息以保持流唤醒。

我使用的早期解决方案之一是:

while (client.IsConnected())
       {
            System.Threading.Thread.Sleep(100);
       }

就在发送一个大文件之后。 然后我依靠接收者自己终止连接。 如果连接终止,就我而言,这将是我需要知道文件已完成传输的信号。