PDA

View Full Version : how to read all datagram packets or limit the no of datagram receiving



pratsam
11th March 2016, 00:48
Language C++
SDK Qt5.5
ISSUE : QUDPSOCKET
OS : LINUX Ubuntu 14.04
Overview of a problem: MY qt application in c++ is receiving udp packets from Webcam from another computer . On receiving frames as udp packets it perform some other task. It all works fine but sometimes when there is sudden change of light, the camera send large number of packets to my end and Qt application fails to read all the packets and as a result Qt readyread signal is not emitted. this is expected because Qt docs says so
Note: An incoming datagram should be read when you receive the readyRead() signal, otherwise this signal will not be emitted for the next datagram.

Now my question is how would I force my application to read all data. Since its udpackets I dont care if I miss some packets but All i want is readyRead to be emitted every time . I looked at some forum and people suggested to use connect before bind which I am doing but still sometimes Qt failed to emit readyRead and when I use wireshark I can see packets are coming to my port from another computer.
So my question is how would I force qt application to read all datagrams. One think i can think of is to force Qt socket to ready only certain no of packets but is this possible in Qt? below is my code





void UDPPacket::slotStartListen()
{
if( !udpSock )
{
udpSock = new QUdpSocket();

}
connect( udpSock, SIGNAL( stateChanged(QAbstractSocket::SocketState)), this, SLOT( onSocketStateChange( QAbstractSocket::SocketState ) ) );

if( !udpSock->bind( UtilStreamingInfo::streamingRecvPortFromGnc, QUdpSocket::ShareAddress|QUdpSocket::ReuseAddressH int ) )
{

if( udpSock->isOpen() )
{

udpSock->close();
}

sigFailedToBind();
return;
}
}

void UDPPacket::onSocketStateChange( QAbstractSocket::SocketState state )
{
qDebug() << " on SOCKET STATE CHANGED";
if( state == QAbstractSocket::BoundState )
{
connect( udpSock, SIGNAL( readyRead() ), this,
SLOT( recvAndProcessData() ) );
}
}

void UDPPacket::recvAndProcessData()
{
while( udpSock->hasPendingDatagrams() )
{
QByteArray byteData;
byteData.resize( udpSock->pendingDatagramSize() );
QHostAddress sender;
quint16 senderPort;
udpSock->readDatagram( byteData.data(), byteData.size(), &sender, &senderPort );


if ( processPacketFunc( byteData ) < 0 )
{
emit sigFinished();
}
}
qDebug() << "end of function";
// SOMETIMES FUNCTION ENDS HERE AND I DONT RECEIVE BYTES
}

jefftee
11th March 2016, 03:16
The whole purpose of that while loop where you check hasPendingDatagrams() is intended to read all datagrams that have been received, so process all datagrams while hasPendingDatagrams() is true then exit your slot. You should then receive another readyRead signal when new datagrams arrive.

I don't think you can force the behavior you're looking for, e.g. one readyRead signal for one datagram, etc.