【发布时间】:2013-11-26 10:08:32
【问题描述】:
我有一个需要改进的库,因为它会丢弃很多数据包。我想接收 RTP-Stream,但流媒体在一毫秒内发送 30-40 个数据包的突发(MJPEG-Stream)。在 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();
}
}
}
我已经知道的:
- 我知道允许UDP丢包,但我还是想 达到最好的结果。如果wireshark可以看到数据包,我 如果可能的话,也希望能够检索它。
- 我知道环形缓冲区在丢失数据包时永远不会满,所以 这也不会让我丢包。我试过 BUFFER_SIZES 100 甚至 1000,但我已经丢失了之前的第一个数据包 总共发送了 1000 个数据包。
所以问题是:从 DatagramSocket 接收尽可能多的数据包的最佳实践是什么?我可以改进对数据包突发的处理吗?
【问题讨论】:
标签: java sockets networking rtp datagram