我有一个需要改进的库,因为它正在丢弃许多数据包。我想接收一个RTP流,但该流传输器在一毫秒内发送30-40个数据包的突发(MJPEG流)。在Wireshark中监控流量时,我可以看到数据包完整。但是,当尝试使用Java接收它们时,我丢失了很多这些数据包。
我已经能够通过实现一个环形缓冲区来改善库的行为,该环形缓冲区在有数据包可用时会不断填充,并有一个单独的读取器线程从该缓冲区中读取数据。但是我仍然无法从我在Wireshark中看到的套接字中获取所有数据包。通过RTP序列号,我可以在读取器线程中监视所处理的数据包是否是预期的数据包。
以下代码正在处理数据包接收:
private volatile byte[][] packetBuffer = new byte[1500][BUFFER_SIZE];
private volatile DatagramPacket[] packets = new DatagramPacket[BUFFER_SIZE];
private volatile int writePointer = 0;
public void run() {
Thread reader = new RTPReaderThread();
reader.start();
while (!rtpSession.endSession) {
// Prepare a packet
packetBuffer[writePointer] = new byte[1500];
DatagramPacket packet = new DatagramPacket(packetBuffer[writePointer], packetBuffer[writePointer].length);
// Wait for it to arrive
if (!rtpSession.mcSession) {
// Unicast
try {
rtpSession.rtpSock.receive(packet);
} catch (IOException e) {
if (!rtpSession.endSession) {
e.printStackTrace();
} else {
continue;
}
}
} else {
// Multicast
try {
rtpSession.rtpMCSock.receive(packet);
} catch (IOException e) {
if (!rtpSession.endSession) {
e.printStackTrace();
} else {
continue;
}
}
}
packets[writePointer] = packet;
this.incrementWritePointer();
synchronized (reader) {
reader.notify();
}
}
}
我已经知道的:
所以问题是:从DatagramSocket接收尽可能多的数据包的最佳实践是什么?我可以改善对数据包突发的处理吗?
尝试使用设置数据报套接字上的SO_RCVBUF大小rtpSock.setReceiveBufferSize(size)
。这仅是对OS的建议,OS可能无法兑现它,尤其是当它太大时。但我会尝试将其设置为(SIZE_OF_PACKET * 30 * 100),其中30是突发数据包的数量,而100是您无法跟上到达速度的毫秒数的猜测。
请注意,如果您的代码通常无法跟上到达速度的处理要求,则操作系统别无选择,只能丢弃数据包。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句