通过网络传输数据时随机字节丢失
-
20-12-2019 - |
题
我的问题是,当我通过本地 LAN 网络传输连续的数据流时,有时随机字节会在此过程中丢失。
目前,代码设置为通过 LAN 每秒传输约 1027 字节左右约 40 次,有时(非常罕见)一个或多个字节会丢失。
让我困惑的是,实际字节并没有“丢失”,它只是设置为 0,无论原始数据如何。(顺便说一下,我使用的是TCP)
这是发送代码:
public void Send(byte[] data)
{
if (!server)
{
if (CheckConnection(serv))
{
serv.Send(BitConverter.GetBytes(data.Length));
serv.Receive(new byte[1]);
serv.Send(data);
serv.Receive(new byte[1]);
}
}
}
和接收代码:
public byte[] Receive()
{
if (!server)
{
if (CheckConnection(serv))
{
byte[] TMP = new byte[4];
serv.Receive(TMP);
TMP = new byte[BitConverter.ToInt32(TMP, 0)];
serv.Send(new byte[1]);
serv.Receive(TMP);
serv.Send(new byte[1]);
return TMP;
}
else return null;
}
else return null;
}
空字节的发送和接收只是为了保持系统同步。我个人认为问题出在系统的接收端。但还无法证明那架飞机。
解决方案
只因你给予 Receive(TMP)
4 字节数组并不意味着它将用 4 字节填充该数组。Receive 调用可以放在任意位置 1
和 TMP.Length
字节到数组中。您必须检查返回的 int
查看数组中填充了多少字节。
网络连接是基于流的而不是基于消息的。您放置到线路上的任何字节都会连接到一个大队列中,并在可用时在另一端读取。所以如果你发送了两个数组 1,1,1,1
和 2,2,2,2
完全有可能在接收方您调用 Receive
3 次 4 字节数组并得到
1,1,0,0
(收到退回的2
)1,1,2,2
(收到退回的4
)2,2,0,0
(收到退回的2
)
所以你需要做的是查看你从 Receive
并继续循环直到你的字节数组已满。
byte[] TMP = new byte[4];
//loop till all 4 bytes are read
int offset = 0;
while(offset < TMP.Length)
{
offset += serv.Receive(TMP, offset, TMP.Length - offset, SocketFlags.None);
}
TMP = new byte[BitConverter.ToInt32(TMP, 0)];
//I don't understand why you are doing this, it is not necessary.
serv.Send(new byte[1]);
//Reset the offset then loop till TMP.Length bytes are read.
offset = 0;
while(offset < TMP.Length)
{
offset += serv.Receive(TMP, offset, TMP.Length - offset, SocketFlags.None);
}
//I don't understand why you are doing this, it is not necessary.
serv.Send(new byte[1]);
return TMP;
最后你说“网络流让你感到困惑”,我愿意打赌上述问题是让你感到困惑的事情之一,进入较低的级别不会消除这些复杂性。如果您希望这些复杂的部分消失,这样您就不必处理它们,您将需要使用第三方库来在库内为您处理它们。
不隶属于 StackOverflow