我正在为VLC开发转发器应用程序并遇到以下问题:
转发器应该接收UDP流并将其转发到另一个中间件,然后中间件将数据包放在时间触发的网络上。我的问题在于VLC发送的数据包的不规则性。一旦VLC开始快速连续发送许多数据包(例如,通常在场景变化期间),目标网络以周期性方式处理消息,导致它丢弃帧。我需要对这些突发数据强制执行零星的行为,因此它们可能会随意到达,但会在最短的到达时间内转发。
到目前为止,我的转发器的工作方式如下:
我把整个东西放在QThread中并将 readyRead()信号连接到我的 receivePacket()插槽,该插槽通过调用再次处理接收,处理和发送数据第二个函数 sendPacket()
我的第一个(天真的)想法就是在每次 QUdpSocket :: writeDatagram 调用之后,让节点睡眠,比如100微秒,但这看起来很糟糕方法,因为我将暂停整个线程,因此(我不确定)丢失来自VLC的数据包在此期间到达。
我想到的另一个解决方案是创建一个单一的 Qtimer ,它会延迟 writeDatagram()调用。但是在这里,我不确定如果另一个数据包到达并再次触发 receivePacket()插槽会发生什么,从而覆盖我试图延迟发送的消息。
有没有简单的方法来解决这个问题?我可以想象的唯一方法是向发送者引入一个内部缓冲区,但这听起来像很多工作,因为我在截止日期前,我想避免这种情况。
提前谢谢!
答案 0 :(得分:0)
据我了解,sendPacket()
方法被快速/经常调用。这意味着您将需要创建一个缓冲区,但这很容易(如果在receivePacket和sendPacket的多个线程中运行,还在访问缓冲区之前/之后添加QMutex :: lock()/ unlock())
在Class.h中:
QTimer *timer; // Timer for periodically calling a sendPacket
QList<MyPacketClass*> buffer; // List containing the packets to be sent
在Class.cpp构造函数中创建带连接的计时器:
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(slotSendPacket()));
timer->start(1000); // Every second
在receivePacket()中,只需将数据添加到列表中:
buffer.append(new MyPacketClass(data));
在class.cpp中创建一个用于连接和从列表中弹出数据的套接字:
void SomeClass::slotSendPacket()
{
if(buffer.size() > 0)
{
sendPacket(buffer.takeAt(0));
}
}
在方法sendPacket(MyPacketClass * inData)中释放分配的内存:
Do_whatever_needs_to_be_done_and_sent(); // Here is writeDatagram();
delete inData; // Free the memory for Packetclass