通过网络传输数据时的随机字节丢失

0 c# networking byte tcp loss

我的问题是,当我通过LOCAL 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]);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

和接收代码:

    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;
    }
Run Code Online (Sandbox Code Playgroud)

发送和接收空字节只是为了使系统保持同步排序.我个人认为问题出在系统的接收方.虽然没能证明那架喷气机.

Sco*_*ain 5

仅仅因为你提供Receive(TMP)一个4字节的数组并不意味着它将用4个字节填充该数组.允许接收调用放入数组之间的任何位置1和TMP.Length字节.您必须检查返回int以查看填充的数组的字节数.

网络连接是基于流的而不是基于消息的.您放入线路的任何字节都会连接到一个大队列,并在另一侧可用时读入.因此,如果您发送了两个数组1,1,1,1,2,2,2,2并且完全有可能在接收端Receive使用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;
Run Code Online (Sandbox Code Playgroud)

最后你说"网络流混淆了你",我愿意打赌上面的问题是困扰你的事情之一,下级不会消除那些复杂性.如果您希望这些复杂的部件消失,那么您不必处理它们,您将需要使用第三方库来为您在库内处理它.