[Resolved] QUdpSocket doesn't work if connected directly to another device (or through switch).
I have a device that sends out a UDP datagram once a second (broadcast).
If I am connected through the entire network, I receive the datagrams fine, but if I am connected directly, or through a switch that isn't connected to the network, then I no longer receive the datagrams.
If I then send a datagram from the Qt application to the device, I then receive the status datagrams for 4-6 seconds, and then it goes dark again.
I have run wireshark, and the computer is receiving the datagrams, they just aren't making it through to QUdpSocket for some reason.
Looking at the "listening" part of this problem. How is your application working exactly? - i.e. are you binding to an IP address / port somthing like:
And then waiting for the readReady() signal?
If you can provide a few more details it could help, if its small-ish you can just paste your udpSocket code... we can take a look :)
Also is this in Windows?
Yes, it is in windows. I am binding and waiting for readyRead().
Bind is like this:
But I have also tried _udpSocket->bind(port);
Both seem to work fine over network, but not using only a switch.
I also had set up a button to manually check hasPendingDatagram(), which returns false.
hmm.... sounds like it could be an IP config type issue...
Of course Wireshark will show you everything! - a great tool, Did you compare the source and dest ip addresses and ports when you sent your data through the "network" and when you sent it via the switch? what are the values? (normally I have to add these columns manually to wireshark as they are not always default)
For the switch I assume it is PC1 ----> switch -----> PC2 or some such with nothing else connected? no possibility for IP address conflicts or such?
I had run the tests before comparing the two, but couldn't remember if I checked the ports, so I did it again.
The source IP (192.168.1.5), source port (10912), destination IP (192.168.1.255 for broadcast), and destination port(10912) are the same whether connected through network or not.
It is connected to an embedded device running Linux, so it is Embedded device --> switch --> PC. It also acts the same if I remove the switch and connect directly to the device. There would not be any IP address conflicts.
When I send a message from the PC to the embedded device, it works fine and receives the message, and the the PC will receive the status messages for 4-6 seconds before halting again.
Ok, so this is strange. I am wandering if somehow the "bindstate" is changing. We can at least check that we are still "bound" with something like:
@if (_udpSocket->state() != _udpSocket->BoundState)
qDebug() << "socket no longer bound!" << endl;@
You may need to periodically check that (QTimer or such), that is if you have not tried this already :o
For our ref the other states are:
QAbstractSocket::UnconnectedState 0 The socket is not connected.
QAbstractSocket::HostLookupState 1 The socket is performing a host name lookup.
QAbstractSocket::ConnectingState 2 The socket has started establishing a connection.
QAbstractSocket::ConnectedState 3 A connection is established.
QAbstractSocket::BoundState 4 The socket is bound to an address and port.
QAbstractSocket::ClosingState 6 The socket is about to close (data may still be waiting to be written).
QAbstractSocket::ListeningState 5 For internal use only.
I have already done this, but just did it again to make sure, and it does stay at 4 (BoundState).
I have both the stateChanged signal connected to a function to monitor states, as well as using my test button to manually check the state, and in both cases it indicates that it stays in state 4.
gah... and this works when you run it through your network. So there just has to be a difference between the two methods we are just not spotting it.
When you run wireshark I am assuming that you cannot connect/bind with your Qt program (because wireshark is connected)?
So, why would the connection timeout after ~4 seconds?...some sort of keep-alive networky thing?
If I had 2 PCs I would run your app on both via this switch and see if you get the same issue on just your original PC or both or none... not asking you to try that as it would take a bit of effort... but I am running out of ideas. My feeling is that it is not strictly a Qt issue.. I feel there is some subtle difference on the network or Windows side, that is my guess.
But if you do/can try it on other PCs that would be my next move....
Running between 2 PCs is a very good idea, I'll give it a shot and report back. I am able to bind when running wireshark. I think it just sniffs but doesn't swallow the datagrams.
I suspect it is some other problem, like the network interface goes to sleep if not connected to a router or something? This doesn't happen on the embedded linux device though, as it still receives messages.
Hmm, maybe I'll also try netcat on the windows machine and see if it can see them. It could be a problem within QT, but not at the UdpSocket level.
Alright, so I figured it out, and it was completely my fault.
I was able to figure it out by getting it running on another PC. When I started the program, the windows firewall popped up and asked what networks I wanted to give the program access to, and default selection was home/work, with public deselected, which triggered something in my head.
When connected to the network, windows thinks it is on a known network, and gives the program access, but when it is not connected through the network, it defaults to unknown network, which gets labelled as Public, and then blocks the program's access.
As to why it is allowed access for about 5 seconds afterwords, I guess windows firewall allows it if you just sent a datagram to that place.
Thanks for all your help. I wouldn't have stumbled upon it without your additional debugging steps. It is greatly appreciated. Keep up the good work :)
haha, no problem... Windoze :o
Well done, good find :)
oh yeah... don't for get to edit your post title with [resolved] at the start... that is the way it works in this forum I am told :)
Thanks for the tip and the help!