Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# UdpClient接收器上的包丢失_C#_Network Programming - Fatal编程技术网

C# UdpClient接收器上的包丢失

C# UdpClient接收器上的包丢失,c#,network-programming,C#,Network Programming,我的应用程序使用UdpClient从其他机器接收图像。 每个图像大小为951000字节,MTU限制为1500字节 所以发送方应用程序必须使用碎片。。。每个发送包都包含包含2 int的头文件 总数 当前_编号 正在接收字节的代码。这是非常密集的比特率,因为视频每30毫秒就有新的帧发送到我的应用程序 我发现自己丢了包裹,我不知道该如何做才能不丢包裹 有人知道怎么解决这个问题吗? 还有更好的办法吗 这是密码 public class PackagePartial { public int to

我的应用程序使用UdpClient从其他机器接收图像。 每个图像大小为951000字节,MTU限制为1500字节

所以发送方应用程序必须使用碎片。。。每个发送包都包含包含2 int的头文件

总数 当前_编号 正在接收字节的代码。这是非常密集的比特率,因为视频每30毫秒就有新的帧发送到我的应用程序

我发现自己丢了包裹,我不知道该如何做才能不丢包裹

有人知道怎么解决这个问题吗? 还有更好的办法吗

这是密码

public class PackagePartial
{
    public int total_count;
    public int current_count; // first package is 1  
    public byte[] buffer;

    public byte[] Serializable()
    {
        // make the Serialize
    }

    public static void DeSerializable(byte[] v)
    {
        total_count = ... ;
        current_count = ... 
        buffer = ... 
    }
}

// the network layer 
int lastPackIndex = 0;
List<byte> collection = new List<byte>();
while(true)
{
      byte[] package = _clientListener.Receive(ref ep);

       PackagePartial p = PackagePartial.DeSerializable(package);

       // indication that i lost package
       if(p.current_count - lastPackIndex != 1 )
       {
         collection.Clear();
         lastPackIndex = 0
         continue;               

       }

       if(p.current_count == p.total_count)
       {
             // image Serialize and send it to the GUI layer as bitmap 
             Image img = ConvertBytesToImage(collection);

             SendToGui(img);

             collection.Clear();

             lastPackIndex = 0

       }
       else
       {
             lastPackIndex = p.current_count
             collection.AddRange(p.Buffer)
       }

不要在接收后将每个包反序列化为中间类

创建一个字节数组列表,并在它们进入时将它们全部填充到其中

一旦另一方完成发送,查看第一方的总计数,并查看List.count是否与总计数匹配

如果是的话,你就拥有了所有的包,现在你可以重新组装图像,只需忽略标题,你就不再需要它们了

由于此时您不需要任何东西,只需要来自每个数据包的数据,因此组装映像应该更快,不再需要对中间类进行序列化


这将最大限度地减少每个图像所需的处理。

通常的方法是使用压缩,如H.264,以减少发送的数据的大小。没有压缩的方法-这是我无法控制和处理的:尝试显著增加listener.Client。ReceiveBufferSize@Yanshof例如我不相信你。涂鸦到@谢谢。。。我试过了,但这是没有帮助的。。。反序列化需要0.459毫秒,而不是1毫秒,所以这不是您所说的每30毫秒在映像上接收一次的问题,951000/1500=634634*.459=291.006。这意味着您每30毫秒需要准备好下一帧时,需要花费291毫秒进行反序列化。怎么能把你的图像处理时间缩短近300毫秒也无济于事呢?没有反序列化我就做不到。我必须知道并更新gui,以防sime packate找不到我或丢失。另一方没有停止发送:-这就是为什么您检查列表中第一个包中的第一个int,并与列表进行比较。计数,如果它们与丢失的包不匹配。如果您在收到每个映像后进行检查,并且每30毫秒获得一个映像,那么您将知道包最多在30毫秒内丢失。