我的问题是,当我通过LOCAL 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;
}
发送和接收空字节只是为了使系统保持同步排序。 我个人认为问题出在系统的接收方。虽然没能证明那架喷气机。
答案 0 :(得分:5)
仅仅因为你给Receive(TMP)
一个4字节数组并不意味着它将用4个字节填充该数组。允许接收调用放入数组中1
和TMP.Length
字节之间的任何位置。您必须检查返回的int
以查看填充的数组的字节数。
网络连接是基于流的,而不是基于消息的。您放入线路的任何字节都会连接到一个大队列,并在另一侧可用时读入。因此,如果您发送了两个数组1,1,1,1
和2,2,2,2
,则完全有可能在接收端使用4字节数组调用Receive
三次并获取
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;
最后你说“网络流混淆了你”,我愿意打赌上面的问题是困扰你的事情之一,下级不会消除那些复杂性。如果你想要这些复杂的部件,那么你就不需要处理它们了,你需要使用第三方库来为你在库内处理它。