mastupristi
mastupristi

Reputation: 1488

Qt5: connectToHost() to receive broadcast udp datagram

Can I use QAbstractSocket::connectToHost() to receive broadcast udp datagrams?

If I try the unmodified broadcastsender/receiver all works and netstat is:

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
udp6       0      0 :::52337                :::*                                12185/./broadcastse 
udp6       0      0 :::45454                :::*                                12172/broadcastrece

I modified broadcastreceiver as follow:

//! [0]
    udpSocket = new QUdpSocket(this);
    udpSocket->bind(45454, QUdpSocket::ShareAddress);
    udpSocket->connectToHost(QHostAddress(QHostAddress::Any),0); // <- added line
//! [0]

Now it does not receive broadcast datagrams, but it receive correctly unicast datagrams.

the netstat command report is:

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
udp6       0      0 ::1:45454               ::1:*                   ESTABLISHED 11488/broadcastrece

I wonder why it seems different local address, and where am I wrong.

best regards Max

Upvotes: 1

Views: 1404

Answers (1)

Mr. Developerdude
Mr. Developerdude

Reputation: 9678

If you look at the official documentation of QUdpSocket you will see the following paragraph which explains how to use QUdpSocket rather well:

The most common way to use this class is to bind to an address and port using bind(), then call writeDatagram() and readDatagram() / receiveDatagram() to transfer data. If you want to use the standard QIODevice functions read(), readLine(), write(), etc., you must first connect the socket directly to a peer by calling connectToHost().

So your call to connectToHost() is not necessary, you should instead just bind and then listen on the signal readyRead() and from the slot, use either readDatagram() to get the raw packet data or receiveDatagram() to get the pre-parsed data.

This might seem counter intuitive, but due to the nature of UDP protocol, there is no connection, and any node may send packets to any other node un-initiated, so once you bind() you can receive UDP packets from anyone.

The source address & port will in that case be part of the datagram itself. You can see this in the parameters to the receiveDatagram() function signature:

qint64 QUdpSocket::readDatagram(char *data, qint64 maxSize, QHostAddress *address = Q_NULLPTR, quint16 *port = Q_NULLPTR)

One note though, you might experience problems communicating over UDP because any translating gateways (NAT routers) will drop all packets since they are un-initiated. This is a common problem and unless you control the routers between the endpoints, will require some clever tricks to get around.

Hope this was informative.

Upvotes: 1

Related Questions