Discussion:
[Interest] Simple UDP listener question
Robert Wood
2014-06-23 12:03:03 UTC
Permalink
Folks,

I've managed to get a simple program going that sends out a UDP packet
to a broadcast address (an Artnet Poll packet) and my embedded software
is receiving this and sending out a Poll reply. Wireshark confirms that
my embedded device is sending out the correct response, however, my Qt
program is not picking up any reply at all. I should say, this is the
first time I've used Qt for networking and it's my first embedded
netowrking project, so I may be missing some very basic point.

I am doing this in MainWindow initialisation:

udpSocSend = new QUdpSocket(this);
udpSocRec = new QUdpSocket(this);
udpSocSend->bind(QHostAddress("192.168.0.18"),6454);
udpSocRec->bind(6454, QUdpSocket::ShareAddress);
connect(udpSocRec, SIGNAL(readyRead()),this,
SLOT(processPendingDatagrams()));

void MainWindow::processPendingDatagrams()
{

while (udpSocRec->hasPendingDatagrams())
{
QByteArray datagram;
datagram.resize(udpSocRec->pendingDatagramSize());
udpSocRec->readDatagram(datagram.data(), datagram.size());
ui->textEdit->setText(tr("Received datagram:
\"%1\"").arg(datagram.data()));

}
}

My udpSocSend is working to send data out (an Artnet Poll), my STM32
(embedded micro) is sending packets back according to Wireshark, but
processPendingDatagrams() flatly refuses to be called!

Wireshark shows this in terms of a reply:

2475 795.416268000 192.168.0.177 192.168.0.18 ARTNET 282 ArtPollReply
(0x2100)

The STM32 is at address 192.168.0.177, my [Linux] Qt machine is
192.168.0.18.

The data in the datagram looks OK mto me on Wireshark.

Can anyone see anything I am doing wrong please?

Thanks!

Rob
Thiago Macieira
2014-06-23 16:10:04 UTC
Permalink
Post by Robert Wood
Folks,
I've managed to get a simple program going that sends out a UDP packet
to a broadcast address (an Artnet Poll packet) and my embedded software
is receiving this and sending out a Poll reply. Wireshark confirms that
my embedded device is sending out the correct response, however, my Qt
program is not picking up any reply at all. I should say, this is the
first time I've used Qt for networking and it's my first embedded
netowrking project, so I may be missing some very basic point.
udpSocSend = new QUdpSocket(this);
udpSocRec = new QUdpSocket(this);
udpSocSend->bind(QHostAddress("192.168.0.18"),6454);
udpSocRec->bind(6454, QUdpSocket::ShareAddress);
Pass the ShareAddress to all instances. Setting it on the second after the
first has bound without the flag will probably result in EADDRINUSE.
Post by Robert Wood
connect(udpSocRec, SIGNAL(readyRead()),this,
SLOT(processPendingDatagrams()));
void MainWindow::processPendingDatagrams()
{
while (udpSocRec->hasPendingDatagrams())
{
QByteArray datagram;
datagram.resize(udpSocRec->pendingDatagramSize());
udpSocRec->readDatagram(datagram.data(), datagram.size());
\"%1\"").arg(datagram.data()));
}
}
My udpSocSend is working to send data out (an Artnet Poll), my STM32
(embedded micro) is sending packets back according to Wireshark, but
processPendingDatagrams() flatly refuses to be called!
Probably because it failed to bind to the port. See above.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Tom Isaacson
2014-06-23 16:12:58 UTC
Permalink
I have a similar piece of code but the one difference I can see is that when I bind the receive socket I also have QUdpSocket::ReuseAddressHint and I use the same parameters on the send socket. I'm not sure if this will help:

udpSocSend = new QUdpSocket(this);
udpSocRec = new QUdpSocket(this);
udpSocSend->bind(QHostAddress("192.168.0.18"), 6454, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
udpSocRec->bind(6454, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
connect(udpSocRec, SIGNAL(readyRead()),this, SLOT(processPendingDatagrams()));

The other thing you can do is receive any errors from the socket:
connect(udpSocRec, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(SocketError(QAbstractSocket::SocketError)));

void SocketError(QAbstractSocket::SocketError)
{
DbgPrintf(dynamic_cast<QUdpSocket *>(sender())->objectName() + QString(": ") + dynamic_cast<QUdpSocket *>(sender())->errorString());
}

Tom Isaacson

-----Original Message-----
From: interest-bounces+tom.isaacson=***@qt-project.org [mailto:interest-bounces+tom.isaacson=***@qt-project.org] On Behalf Of Robert Wood
Sent: Tuesday, 24 June 2014 12:03 a.m.
To: ***@qt-project.org
Subject: [Interest] Simple UDP listener question

Folks,

I've managed to get a simple program going that sends out a UDP packet to a broadcast address (an Artnet Poll packet) and my embedded software is receiving this and sending out a Poll reply. Wireshark confirms that my embedded device is sending out the correct response, however, my Qt program is not picking up any reply at all. I should say, this is the first time I've used Qt for networking and it's my first embedded netowrking project, so I may be missing some very basic point.

I am doing this in MainWindow initialisation:

udpSocSend = new QUdpSocket(this);
udpSocRec = new QUdpSocket(this);
udpSocSend->bind(QHostAddress("192.168.0.18"),6454);
udpSocRec->bind(6454, QUdpSocket::ShareAddress);
connect(udpSocRec, SIGNAL(readyRead()),this, SLOT(processPendingDatagrams()));

void MainWindow::processPendingDatagrams()
{

while (udpSocRec->hasPendingDatagrams())
{
QByteArray datagram;
datagram.resize(udpSocRec->pendingDatagramSize());
udpSocRec->readDatagram(datagram.data(), datagram.size());
ui->textEdit->setText(tr("Received datagram:
\"%1\"").arg(datagram.data()));

}
}

My udpSocSend is working to send data out (an Artnet Poll), my STM32 (embedded micro) is sending packets back according to Wireshark, but
processPendingDatagrams() flatly refuses to be called!

Wireshark shows this in terms of a reply:

2475 795.416268000 192.168.0.177 192.168.0.18 ARTNET 282 ArtPollReply
(0x2100)

The STM32 is at address 192.168.0.177, my [Linux] Qt machine is 192.168.0.18.

The data in the datagram looks OK mto me on Wireshark.

Can anyone see anything I am doing wrong please?

Thanks!

Rob
Robert Wood
2014-06-23 17:41:31 UTC
Permalink
Thanks for the suggestions, but no joy with anything still. Not getting
any errors, let alone receiving any packets.

I'm wondering whether I have fundamentally misunderstood something about
what I am doing. Or trying to do.

The QHostAddress("192.168.0.18") should be the IP address of my computer
shouldn't it? I'm not really clear why this is necessary as I would
assume Qt would automatically pick that up? Or is it in case you have
more than one NIC and you are telling the program which one to listen
on/send from?

Is it necessary to have a second socket for reading or can you read from
and write to the same socket? I can't see anything on the broadcast
receive example that specifically says only read or that it is to be
set-up as a read socket, not write.

I assume that for the method I have tried below it should be OK if the
packet my embedded device sends out is a unicast packet. ie It can be
send from 192.168.0.177 (the STM32) to 192.168.0.18 (my computer) and
the STM32 does not have to send out to 192.168.0.255 for the code I've
taken from the example?

Can't think of anything else to ask at the moment, hopefully one of
these questions will make obvious what the issue is!

Thanks again.
Post by Robert Wood
udpSocSend = new QUdpSocket(this);
udpSocRec = new QUdpSocket(this);
udpSocSend->bind(QHostAddress("192.168.0.18"), 6454, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
udpSocRec->bind(6454, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
connect(udpSocRec, SIGNAL(readyRead()),this, SLOT(processPendingDatagrams()));
connect(udpSocRec, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(SocketError(QAbstractSocket::SocketError)));
void SocketError(QAbstractSocket::SocketError)
{
DbgPrintf(dynamic_cast<QUdpSocket *>(sender())->objectName() + QString(": ") + dynamic_cast<QUdpSocket *>(sender())->errorString());
}
Tom Isaacson
-----Original Message-----
Sent: Tuesday, 24 June 2014 12:03 a.m.
Subject: [Interest] Simple UDP listener question
Folks,
I've managed to get a simple program going that sends out a UDP packet to a broadcast address (an Artnet Poll packet) and my embedded software is receiving this and sending out a Poll reply. Wireshark confirms that my embedded device is sending out the correct response, however, my Qt program is not picking up any reply at all. I should say, this is the first time I've used Qt for networking and it's my first embedded netowrking project, so I may be missing some very basic point.
udpSocSend = new QUdpSocket(this);
udpSocRec = new QUdpSocket(this);
udpSocSend->bind(QHostAddress("192.168.0.18"),6454);
udpSocRec->bind(6454, QUdpSocket::ShareAddress);
connect(udpSocRec, SIGNAL(readyRead()),this, SLOT(processPendingDatagrams()));
void MainWindow::processPendingDatagrams()
{
while (udpSocRec->hasPendingDatagrams())
{
QByteArray datagram;
datagram.resize(udpSocRec->pendingDatagramSize());
udpSocRec->readDatagram(datagram.data(), datagram.size());
\"%1\"").arg(datagram.data()));
}
}
My udpSocSend is working to send data out (an Artnet Poll), my STM32 (embedded micro) is sending packets back according to Wireshark, but
processPendingDatagrams() flatly refuses to be called!
2475 795.416268000 192.168.0.177 192.168.0.18 ARTNET 282 ArtPollReply
(0x2100)
The STM32 is at address 192.168.0.177, my [Linux] Qt machine is 192.168.0.18.
The data in the datagram looks OK mto me on Wireshark.
Can anyone see anything I am doing wrong please?
Thanks!
Rob
_______________________________________________
Interest mailing list
http://lists.qt-project.org/mailman/listinfo/interest
Ian Monroe
2014-06-23 17:45:46 UTC
Permalink
On Mon, Jun 23, 2014 at 10:41 AM, Robert Wood
Post by Robert Wood
The QHostAddress("192.168.0.18") should be the IP address of my computer
shouldn't it? I'm not really clear why this is necessary as I would
assume Qt would automatically pick that up? Or is it in case you have
more than one NIC and you are telling the program which one to listen
on/send from?
You could bind to 0.0.0.0 instead I think.

Ian
m***@rpzdesign.com
2014-06-23 18:04:04 UTC
Permalink
Maybe you should only use 1 socket instead of 2.

UDP only needs to bind to receive, but can send without binding as long
as you use sendto( ) calls.
Post by Ian Monroe
On Mon, Jun 23, 2014 at 10:41 AM, Robert Wood
Post by Robert Wood
The QHostAddress("192.168.0.18") should be the IP address of my computer
shouldn't it? I'm not really clear why this is necessary as I would
assume Qt would automatically pick that up? Or is it in case you have
more than one NIC and you are telling the program which one to listen
on/send from?
You could bind to 0.0.0.0 instead I think.
Ian
_______________________________________________
Interest mailing list
http://lists.qt-project.org/mailman/listinfo/interest
Robert Wood
2014-06-23 18:21:21 UTC
Permalink
There does seem to be a sendTo() function within the class. If I don't
bind it and use writeDatagram it doesn't send anything out.
Post by m***@rpzdesign.com
Maybe you should only use 1 socket instead of 2.
UDP only needs to bind to receive, but can send without binding as long
as you use sendto( ) calls.
Post by Ian Monroe
On Mon, Jun 23, 2014 at 10:41 AM, Robert Wood
Post by Robert Wood
The QHostAddress("192.168.0.18") should be the IP address of my computer
shouldn't it? I'm not really clear why this is necessary as I would
assume Qt would automatically pick that up? Or is it in case you have
more than one NIC and you are telling the program which one to listen
on/send from?
You could bind to 0.0.0.0 instead I think.
Ian
_______________________________________________
Interest mailing list
http://lists.qt-project.org/mailman/listinfo/interest
_______________________________________________
Interest mailing list
http://lists.qt-project.org/mailman/listinfo/interest
Thiago Macieira
2014-06-23 18:37:59 UTC
Permalink
Post by Robert Wood
There does seem to be a sendTo() function within the class. If I don't
bind it and use writeDatagram it doesn't send anything out.
writeDatagram() takes a destination address and port. If that doesn't work,
please provide a testcase.

Unfortunately, UDP is quite brittle.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Robert Wood
2014-06-23 18:50:44 UTC
Permalink
Sorry, I meant to write there does *not( seem to be a sendTo() function.

Writing out with writeDatagram() works just fine as long as I bind
first; it's the receiving part that just will not work, even if I
faithfully follow the example. I must be missing a fundamental aspect of
this somewhere, but I just can't see what.
Post by Thiago Macieira
Post by Robert Wood
There does seem to be a sendTo() function within the class. If I don't
bind it and use writeDatagram it doesn't send anything out.
writeDatagram() takes a destination address and port. If that doesn't work,
please provide a testcase.
Unfortunately, UDP is quite brittle.
Thiago Macieira
2014-06-23 19:33:55 UTC
Permalink
Post by Robert Wood
Sorry, I meant to write there does *not( seem to be a sendTo() function.
Writing out with writeDatagram() works just fine as long as I bind
first; it's the receiving part that just will not work, even if I
faithfully follow the example. I must be missing a fundamental aspect of
this somewhere, but I just can't see what.
writeDatagram automatically binds for you. It should be enough to send a
datagram from a randomly allocated port.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Robert Wood
2014-06-23 22:27:58 UTC
Permalink
It can't be a randomly allocated port though, it has to be port 6454.
Post by Thiago Macieira
Post by Robert Wood
Sorry, I meant to write there does *not( seem to be a sendTo() function.
Writing out with writeDatagram() works just fine as long as I bind
first; it's the receiving part that just will not work, even if I
faithfully follow the example. I must be missing a fundamental aspect of
this somewhere, but I just can't see what.
writeDatagram automatically binds for you. It should be enough to send a
datagram from a randomly allocated port.
Bob Hood
2014-06-23 22:45:03 UTC
Permalink
Post by Robert Wood
It can't be a randomly allocated port though, it has to be port 6454.
I realize I've come into this conversation late, but something like:

receive_socket = new QUdpSocket(this);
receive_socket->bind(QHostAddress::Any, 6454);

wouldn't work for you?
Robert Wood
2014-06-24 08:38:22 UTC
Permalink
Yes, Bob, that's exactly it.

On 192.168.0.18 I have stripped it right down to this this:


udpSocRec = new QUdpSocket(this);
udpSocRec->bind(QHostAddress::Any, 6454);

connect(udpSocRec, SIGNAL(readyRead()),this,
SLOT(processPendingDatagrams()));

processPendingDatagrams() never gets called, even when Wireshark on
192.168.0.18 shows this message:


246843 367.240816000 192.168.0.19 192.168.0.18 ARTNET 60 ArtPoll (0x2000)

When I get my laptop which is on 192.168.0.19 to send a packet out.

Wireshark also tells me this packet is:

User Datagram Protocol, Src Port: 6454 (6454), Dst Port: 6454 (6454)

I've tried changing the port to 123 to capture incoming NTP packets
which, again, Wireshark says are present, but to no avail.

Thanks,

Rob
Post by Bob Hood
Post by Robert Wood
It can't be a randomly allocated port though, it has to be port 6454.
receive_socket = new QUdpSocket(this);
receive_socket->bind(QHostAddress::Any, 6454);
wouldn't work for you?
_______________________________________________
Interest mailing list
http://lists.qt-project.org/mailman/listinfo/interest
Rainer Wiesenfarth
2014-06-24 10:12:24 UTC
Permalink
Post by Robert Wood
Yes, Bob, that's exactly it.
udpSocRec = new QUdpSocket(this);
udpSocRec->bind(QHostAddress::Any, 6454);
connect(udpSocRec, SIGNAL(readyRead()),this,
SLOT(processPendingDatagrams()));
processPendingDatagrams() never gets called, even when Wireshark on
246843 367.240816000 192.168.0.19 192.168.0.18 ARTNET 60 ArtPoll (0x2000)
When I get my laptop which is on 192.168.0.19 to send a packet out.
User Datagram Protocol, Src Port: 6454 (6454), Dst Port: 6454 (6454)
What does "netstat -an" say when your UDP listener is running? You
should find your app as "UDP 0.0.0.0:6454" for IPv4 and/or as "UDP
[::]:6454" for IPv6.

Best Regards / Mit freundlichen Grüßen
Rainer Wiesenfarth
--
Software Engineer | Trimble Imaging Division
Rotebühlstraße 81 | 70178 Stuttgart | Germany
Office +49 711 22881 0 | Fax +49 711 22881 11
http://www.trimble.com/imaging/ | http://www.inpho.de/

Trimble Germany GmbH, Am Prime Parc 11, 65479 Raunheim
Eingetragen beim Amtsgericht Darmstadt unter HRB 83893,
Geschäftsführer: Dr. Frank Heimberg, Hans-Jürgen Gebauer
Robert Wood
2014-06-24 11:02:57 UTC
Permalink
Hi Rainer,

It says this:

udp 0 0 0.0.0.0:6454 0.0.0.0:*

If I stop my app, that disappears, if I change it to listen on
192.168.0.18 by changing this line:

udpSocRec->bind(QHostAddress("192.168.0.18"), 6454);

I get this:

udp 0 0 192.168.0.18:6454 0.0.0.0:*

So, I assume that means it's setting up the port OK. I can only assume I
am missing out one vital step that isn't specified in the examples.

Thanks,

Rob
Post by Rainer Wiesenfarth
What does "netstat -an" say when your UDP listener is running? You
should find your app as "UDP 0.0.0.0:6454" for IPv4 and/or as "UDP
[::]:6454" for IPv6.
Rainer Wiesenfarth
2014-06-24 11:17:11 UTC
Permalink
Post by Robert Wood
udp 0 0 0.0.0.0:6454 0.0.0.0:*
If I stop my app, that disappears, [...]
Ok, so your app can create the socket. Just to make sure: You _are_
running an event loop (Q{Core,}Application::exec())!?

Best Regards / Mit freundlichen Grüßen
Rainer Wiesenfarth
--
Software Engineer | Trimble Imaging Division
Rotebühlstraße 81 | 70178 Stuttgart | Germany
Office +49 711 22881 0 | Fax +49 711 22881 11
http://www.trimble.com/imaging/ | http://www.inpho.de/

Trimble Germany GmbH, Am Prime Parc 11, 65479 Raunheim
Eingetragen beim Amtsgericht Darmstadt unter HRB 83893,
Geschäftsführer: Dr. Frank Heimberg, Hans-Jürgen Gebauer
Robert Wood
2014-06-24 11:31:29 UTC
Permalink
Yes, I'm creating a standard Qt GUI using Qt Creator. With the same app,
I can send out packets over and over again. I've just got that bit
removed at the moment in an attempt to simplify things as much as possible.
Post by Rainer Wiesenfarth
Post by Robert Wood
udp 0 0 0.0.0.0:6454 0.0.0.0:*
If I stop my app, that disappears, [...]
Ok, so your app can create the socket. Just to make sure: You _are_
running an event loop (Q{Core,}Application::exec())!?
Best Regards / Mit freundlichen Grüßen
Rainer Wiesenfarth
_______________________________________________
Interest mailing list
http://lists.qt-project.org/mailman/listinfo/interest
Robert Wood
2014-06-24 14:48:08 UTC
Permalink
Hmmm, it's an issue with my desktop (192.168.0.18). If I swap things
around and send from my desktop to the laptop, the laptop is working and
seeing the packets. I can use netcat to test things both ways and that
too will acdept nothing into the desktop. Weird. So, it's sack all to do
with Qt after all that. :~(

Thanks for all help and suggestions.
Post by Rainer Wiesenfarth
Post by Robert Wood
udp 0 0 0.0.0.0:6454 0.0.0.0:*
If I stop my app, that disappears, [...]
Ok, so your app can create the socket. Just to make sure: You _are_
running an event loop (Q{Core,}Application::exec())!?
Best Regards / Mit freundlichen Grüßen
Rainer Wiesenfarth
_______________________________________________
Interest mailing list
http://lists.qt-project.org/mailman/listinfo/interest
Konrad Rosenbaum
2014-06-25 09:23:49 UTC
Permalink
Hi,

check the Firewall on this Desktop - most of the time when I have these
kinds of problems it's the firewall's fault. Wireshark usually shows all
packets that arrive at the ethernet card before they are filtered, then
the firewall kicks in and last the program may (or may not) receive
something.


regards, Konrad
Post by Robert Wood
Hmmm, it's an issue with my desktop (192.168.0.18). If I swap things
around and send from my desktop to the laptop, the laptop is working and
seeing the packets. I can use netcat to test things both ways and that
too will acdept nothing into the desktop. Weird. So, it's sack all to do
with Qt after all that. :~(
Thiago Macieira
2014-06-24 14:51:45 UTC
Permalink
Post by Robert Wood
I've tried changing the port to 123 to capture incoming NTP packets
which, again, Wireshark says are present, but to no avail.
You can't bind to port 123. That's a privileged port.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Thiago Macieira
2014-06-23 23:17:09 UTC
Permalink
Post by Robert Wood
It can't be a randomly allocated port though, it has to be port 6454.
The sender port is randomly allocated, if you don't specify one.

If you need it to be sent *from* 6454, then you need to bind before
writeDatagram.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Robert Wood
2014-07-02 13:39:58 UTC
Permalink
Just for the sake of preventing someone banging their head against a
brick wall for ages in the future, this turned out to be the fact that
some of the returning UDP packets were being picket up by the *sending*
socket. If I only open one socket, both sending and receiving on it, the
whole thing works a treat. Or, of course, if I have a second
processPendingDatagrams type function that listens for incoming packets
on the "sending" socket.

I suspect many people haven't come across this before because, I guess,
normally, you don't send and receive on the same port. Artnet specifies
you have to and so this issue raises its ugly head.
Post by Robert Wood
Folks,
I've managed to get a simple program going that sends out a UDP packet
to a broadcast address (an Artnet Poll packet) and my embedded software
is receiving this and sending out a Poll reply. Wireshark confirms that
my embedded device is sending out the correct response, however, my Qt
program is not picking up any reply at all. I should say, this is the
first time I've used Qt for networking and it's my first embedded
netowrking project, so I may be missing some very basic point.
udpSocSend = new QUdpSocket(this);
udpSocRec = new QUdpSocket(this);
udpSocSend->bind(QHostAddress("192.168.0.18"),6454);
udpSocRec->bind(6454, QUdpSocket::ShareAddress);
connect(udpSocRec, SIGNAL(readyRead()),this,
SLOT(processPendingDatagrams()));
void MainWindow::processPendingDatagrams()
{
while (udpSocRec->hasPendingDatagrams())
{
QByteArray datagram;
datagram.resize(udpSocRec->pendingDatagramSize());
udpSocRec->readDatagram(datagram.data(), datagram.size());
\"%1\"").arg(datagram.data()));
}
}
My udpSocSend is working to send data out (an Artnet Poll), my STM32
(embedded micro) is sending packets back according to Wireshark, but
processPendingDatagrams() flatly refuses to be called!
2475 795.416268000 192.168.0.177 192.168.0.18 ARTNET 282 ArtPollReply
(0x2100)
The STM32 is at address 192.168.0.177, my [Linux] Qt machine is
192.168.0.18.
The data in the datagram looks OK mto me on Wireshark.
Can anyone see anything I am doing wrong please?
Thanks!
Rob
_______________________________________________
Interest mailing list
http://lists.qt-project.org/mailman/listinfo/interest
Thiago Macieira
2014-07-02 15:21:26 UTC
Permalink
Post by Robert Wood
I suspect many people haven't come across this before because, I guess,
normally, you don't send and receive on the same port. Artnet specifies
you have to and so this issue raises its ugly head.
I think sending and receiving using the same port is the normal case.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Loading...