PDA

View Full Version : Using QUdpSocket to detect peripheral via a broadcast



Eos Pengwern
8th November 2010, 14:28
As the title suggests, I'm trying to use a QUdpSocket to detect a peripheral which is attached to the host computer. The desired sequence-of-events is:

1. Host broadcasts an "Is anybody there" message to its whole network.
2. The peripheral, on receiving the broadcast, sends a message back saying "here I am".
3. The host receives the response, and checks whether it is a valid "here I am" message; if not, it ignores it and waits for the next message; if it is, then it makes a notes of the sender's address so further communications can be addressed exclusively to the peripheral.

Here's my code:



// The QByteArray "datagram" initially contains the "Is anybody there" message
QUdpSocket udpSocket;
udpSocket.bind(QHostAddress::Any, 2101);
udpSocket.writeDatagram(datagram.data(), datagram.size(),
QHostAddress::Broadcast, 2101);

datagram.resize(sizeof(DISCOVERY_RESPONSE));
QHostAddress senderAddress;
quint16 senderPort;
QTime timeout_counter;
timeout_counter.start();
while (timeout_counter.elapsed() < TIMEOUT)
{
if (udpSocket.hasPendingDatagrams())
{
int returnedSize = udpSocket.readDatagram(datagram.data(), datagram.size(),
&senderAddress, &senderPort);
int responseSize = sizeof(DISCOVERY_RESPONSE);
if (returnedSize == responseSize)
{
// Great joy
DISCOVERY_RESPONSE *response = reinterpret_cast<DISCOVERY_RESPONSE *>(datagram.data());
}
}
else QCoreApplication::processEvents();
}


What actually happens is that the "udpSocket.readDatagram" line immediately receives the host's own broadcast but, realising that this isn't what its looking for, discards it and carries on listening. The remote peripheral, meanwhile, receives the broadcast and responds to it. However, the QUdpSocket does not received the response, it just carries on looping till it times out.

If I happen to know the peripheral's IP address already (for example, by interrogating my router) and I hard-code this addess in place of QHostAddress::Broadcast in the above code, then everything behaves perfectly. It's as if, having once received data from one address (i.e. its own broadcast), the QUdpSocket has become blind to data sent from anywhere else, despit having been bound at the beginning to QHostAddress::Any. Is there a way that I can reset it, or is there something else that I'm doing wrong here?

Thanks,
Stephen.

Added after 8 minutes:

How odd...

If I disable my firewall, then it works properly. Yet even with the firewall in place, the broadcast message got out to the peripheral, and the message from the peripheral was getting back whenever it had been addressed directly as opposed to being addressed via a broadcast.

It's as if the firewall shuts down incoming messages whenever it detects that a broadcast has taken place. Very antisocial.

So, today I've learned nothing about QUdpSockets but plenty about Firewalls.

Stephen.

wysota
8th November 2010, 14:50
It's usually a good idea to be standard conformant whenever you can, especially when there are already required libraries available.

http://en.wikipedia.org/wiki/Zeroconf
http://www.dns-sd.org/
http://doc.trolltech.com/qq/qq23-bonjour.html

Eos Pengwern
8th November 2010, 17:02
Thank you. What I'm doing is intended to be compliant with the GigE Vision standard for cameras and other optical devices, hence the use of UDP rather than TCP/IP. I'm not aware of anything available off-the-shelf for this, but I do remember having serious firewall problems when using a Dalsa GigE Vision camera with the vendor's own software a couple of years ago - basically I had to disable the firewall whenever I wanted to use the camera. I'd forgotten all about it until today. Maybe I should just use different firewall software.

wysota
9th November 2010, 10:30
Thank you. What I'm doing is intended to be compliant with the GigE Vision standard for cameras and other optical devices,
I don't think the standard deals with service discovery. You can still use bonjour/zeroconf for that.


hence the use of UDP rather than TCP/IP.
Who's talking about TCP here?


basically I had to disable the firewall whenever I wanted to use the camera. I'd forgotten all about it until today. Maybe I should just use different firewall software.
Decent firewalls handle UPnP connections well, that's a standard too.

adzajac
9th November 2010, 11:21
Hi

First of all when you're using QHostAddress::Broadcast it means that you're datagrams to 255.255.255.255 IP address and they will be received only in your LAN segment. It means that if your devices are somewhere outside your LAN they do not receive anything.