【问题标题】:lost of packages on UdpClient receiverUdpClient 接收器上的包丢失
【发布时间】:2015-06-25 04:21:11
【问题描述】:

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

所以发送方应用程序必须使用分片...并且每个发送包都包含包含 2 个 int 的标头

  1. 总数
  2. current_number

接收字节的代码..这是非常密集的比特率,因为视频每 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)
       }

【问题讨论】:

  • 通常的方法是采用压缩(例如 H.264)来减小发送数据的大小。
  • 没有办法压缩 - 这是我无法控制和处理的东西:(
  • 尝试显着增加 listener.Client.ReceiveBufferSize
  • @Yanshof:我不相信你。
  • Graffito@ 谢谢...我尝试了,但这无济于事

标签: c# network-programming


【解决方案1】:

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

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

一旦对方完成发送,在第一个中查找总计数并查看 List.Count 是否与总计数匹配。

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

由于此时您不需要任何东西,只需要来自每个数据包的数据,因此组装图像应该更快(不再涉及到中间类的序列化)。

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

【讨论】:

  • 不行...反序列化需要 0.459 毫秒(不到一毫秒) - 所以这不是问题
  • 您说您每 30 毫秒接收一次图像,951000/1500 = 634, 634 * .459 = 291.006。这意味着当您需要每 30 毫秒为下一帧做好准备时,您将花费 291 毫秒进行反序列化。如何将图像处理时间缩短近 300 毫秒?
  • 如果没有反序列化,我无法做到这一点。我必须知道并更新 gui,以防 sime packate 没有找到我或丢失。
  • 而对方没有停止发送:-(
  • 这就是为什么您检查列表中第一个包中的第一个 int 并与 list.count 进行比较,如果它们与您丢失的包不匹配。如果您在收到每张图片后进行检查,并且每 30 毫秒获取 1 张图片,您将在最多 30 毫秒内知道包裹丢失。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多