【问题标题】:Why is my MulticastSocket only receiving every 256th packet?为什么我的 MulticastSocket 只接收每 256 个数据包?
【发布时间】:2014-03-13 21:42:32
【问题描述】:

我正在 MATLAB 中订阅多播 UDP 流。这不能在本地完成,所以我使用的是java.net.MulticastSocket 对象。每个 UDP 数据包都标记有一些元数据,特别是序列计数。每次我的数据源发送一个 UDP 数据包时,该序列计数都会增加。

这是我的骨架代码:

s = java.net.MulticastSocket(50001);
s.setSoTimeout(15000);
s.setReuseAddress(1);
s.setReceiveBufferSize(32768);
s.joinGroup(java.net.InetAddress.getByName('239.255.0.4'));
p = java.net.DatagramPacket(zeros(1, 1600, 'int8'), 1600);

ii = 1;
d = cell(10000,1);

while ii < 10000
    s.receive(p);
    d{ii} = p.getData;
    d{ii} = d{ii}(1:p.getLength);

    ii = ii + 1;
end

一旦我捕获了所有数据,我就可以对其进行后处理;那一点并不重要。

在捕获 10,000 个这样的数据包后,我查看了序列计数,结果发现我丢失了数据包。这还算公平;毕竟这是 UDP,所以不能保证接收到流量。然而,真正有趣的是我只收到每 256 个数据包:

sequenceCnt =
    ...
    56637
    56893
    57149
    57405
    57661
    57917
    58173
    58429
    58685
    58941
    59197
    59453
    ...

我让 Wireshark 运行并观察传入的数据流,并且数据包肯定在增加。因此,我的计算机可以看到完整的多播流(即不丢弃数据包,因为 UDP 不保证传送),但是这个小的 MATLAB/Java 代码无法跟上流。

知道发生了什么吗?我的 Java 经验基本上为零,因此我们将不胜感激。

【问题讨论】:

  • 我无法完全弥补你的 while 循环; d{ii} ... 行是简单的分配吗?
  • 是的,dcell array。我所做的只是获取数据,然后根据长度trimming。我在这里使用元胞数组而不是矩阵,因为不能保证数据流的长度大小相同。 (MATLAB 仅允许您在行数相同的情况下构建矩阵。)
  • 只有在收到所有数据后,您能否将分配给此元胞数组的处理后处理?
  • 不,如果需要,我可以在里面做。这就是我的原始代码。出于这个问题的目的,我想确保我的处理代码不是数据被丢弃的瓶颈,所以我将后处理移到了循环之外
  • 啊,好的,所以即使有这段代码,你看到问题了吗?有趣...我认为增加缓冲区大小也无济于事?

标签: java matlab udp multicast


【解决方案1】:

即使您的接收器丢失了一些数据包(即数据报),也极不可能始终准确地丢失 255/256。您是否或可以检查在您的接收器运行的时间间隔内,wireshark 显示的数据包数量(根据需要过滤)?

我的猜测是,由于解析数据包内容时的字节顺序或对齐方式,您的 seq 值是错误的,而您没有显示。确保接收方读取发送方用于 seq 的相同的两个(?)字节,并且以正确的顺序——wireshark 应该显示准确的布局。如果您使用 DataInputStream Java 将多字节数字定义为大端,并且所有内容都是字节对齐的;对于其他我不能说的代码。

另外,我假设单元分配或“修剪”操作(总是)复制字节数组的选定部分,例如(可能使用)Arrays.copyOf(T[],int)。 DatagramSocket 和 DatagramPacket 本身重用相同的缓冲区,因此如果在每次迭代中分配 getData() reference,您将有 N 个指针全部指向一个缓冲区,该缓冲区仅包含最后一次接收后的数据.

【讨论】:

  • 今天早上我会看看字节序,但数据包中的其他所有内容都正确形成。事实上,我像这样放弃了 2 的倍数,这让我觉得这实际上不是一个下降,而是在其他地方......
  • 字节序可能是一个看起来像的问题。我的话有一半是正确的。可能是我正在研究的规范的问题。
  • 没有更仔细地查看字节序,我觉得很愚蠢。我将数据从uint8 类型转换为uint16,MATLAB 使用给定向量的第一个元素作为 least 有效字节进行类型转换(即,如果我有单词0x12ab 然后@ 987654324@ 和 d(2) == 0x12)。更糟糕的是,我的一些虚拟数据是回文(例如0x3030),所以有一半时间它看起来是正确的。感谢您让我从不同的角度看待这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-17
  • 2019-03-27
  • 2018-06-27
  • 1970-01-01
  • 2017-05-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多