OK, guys! I figured that one out and it is indeed a bug in Qt!
After enabling the debug output in QtNetworkd4.dll it was obvious what was causing the 100% CPU utilization. The slot QAbstractSocketPrivate::_q_canReadNotification() was called continuously resulting in the following debug output:
QAbstractSocketPrivate::_q_canReadNotification() WSA error : WSAECONNRESET more details (An existing connection was forcibly closed by the remote host.) QNativeSocketEnginePrivate::nativeHasPendingDatagrams() == false QAbstractSocketPrivate::_q_canReadNotification()
Hmm, WSAECONNRESET for a UDP socket? I did a web search and after reading a few not that informative posts in different forums I finally came across that one:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4361783
In a nutshell, if a UDP packet is sent to a host that is online but has nothing listening at the destination port, a ICMP packet port unreachable is sent in response. Windows will buffer this ICMP packet and next time you try to read a datagram from your socket you’ll get a WSAECONNRESET. That’s not that bad though because only that read will fail (unless you have multiple ICMPs buffered) and the next one would succeed, as long as you have any UDP datagram buffered.
The problem in Qt’s implementation is that the function QNativeSocketEnginePrivate::nativeHasPendingDatagrams() is called to check whether a datagram is available by peeking the data available. Upon a socket error WSAECONNRESET it should either emit a really meaningful error message, or should simply try to do an actual read and thus remove the ICMP packet from the OS queue. My patch does the latter.
One idea for a workaround would be to try to read a datagram once each second which is quite ugly IMHO… Best would be if the next minor release of Qt fixes!
Regards,
Peter
