我通过localhost使用TCP套接字在我的C#/ Mono程序和Raspbian上的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);
目前,我使用两次连续传输将数据发送到脚本。
这是一个单声道的bug吗?或者我在这里做错了什么?
答案 0 :(得分:0)
之前我遇到过这个问题。 基本上,您需要考虑网络操作的实际工作方式。
当你这样做时
networkStream.Write(byteArray, 0, size);
是的,您正在将其写入流中,但流需要保持打开状态,直到客户端完成数据接收为止。
在我的情况下 - 我发送数据,然后假设networkStream.Read操作已经完成,然后在'Write'端关闭连接。
如果写入的客户端关闭了连接,在他们“认为”文件/数据被写入之后,但在接收者实际上“读取”了数据之前,那么你可以遇到部分数据是丢失。
解决此问题的方法是使用您的网络创建协议。
一种常见的策略是测量您希望发送的数据量,然后将其作为长变量发送到有效负载之前。 然后,接收器将知道预期有多少数据,并将从流中读取该数据量。 完成后,接收方应该让客户知道他们已经收到了所有数据。
写入客户端可以“等待”此确认消息,以保持流唤醒。
我使用的早期解决方案之一是:
while (client.IsConnected())
{
System.Threading.Thread.Sleep(100);
}
发送大文件后立即发送。 然后我依靠接收器自己终止连接。 如果连接终止,在我的情况下,它将是我需要知道文件已完成传输的信号。