mardi 21 avril 2015

QtUdpSocket - Sending too large datagram doesn't fail with "DatagramTooLargeError"

I came across a strange problem with QUdpSocket. Maybe this problem is known to you or any of you know how to handle it.

I'm developing with Qt 5.4.1 x86 on Windows 7 (x64), no firewalls are active.

Sending an UDP datagrams with "no fragment" bit set sometimes doesn't produce "DatagramTooLargeError" as expected but "SocketTimeoutError".

Setting "No Fragment" bit is done by native "setsockopt" method since Qt doesn't support this flag.

_Socket.bind(QHostAddress::AnyIPv4, 0, QAbstractSocket::ShareAddress);
unsigned int Flag = 1;
int ret = setsockopt(_Socket.socketDescriptor(), IPPROTO_IP, IP_DONTFRAGMENT, (const char*) &Flag, sizeof(Flag));

As I found out, "WSASendTo" in qnativesocketengine_win.cpp:1307 doesn't return SOCKET_ERROR in that case which shouldn't be the case. My first thought was, that setting "No Fragment" bit was lost some where, but how and where?

Following snippet of code causes this behaviour. Result return 16384 here which shouldn't be the case since "no Fragmentation" means, sending that large datagram is not possible.

qint64 Result = _Socket.writeDatagram((const char*) Message, 16384, _SenderAddress, _SenderPort);

Subsequent calls of the same "Send" command again give the expected result by returning an error. Calling the same command after one minute socket idle or so, no error is returned again, but then fail again the next call as expected.

This is a fully working Example Project to reproduce the described behaviour.

You should start this demo on two different computers. Enter the receiver IP address and port, and select an local sender adapter to bind to. Port can be left to zero. Then set "Don't fragment" and set the buffer size to 16384. After that you can press the "Send" button.

You will see something like this after pressing the send for the first time:

11:30:49,577: Sent 16384 bytes to

Pressing the button again and you will get the expected error message

Error sending datagram (Datagram was too large to send)

However after waiting a minute or so, you won't get that error again.

I was not able to reproduce this behaviour with pure windows socket implementation.

PS: I filled an Qt Bug report at QTBUG-45471. I refrain to repeat the complete text of the bug report here.

Aucun commentaire:

Enregistrer un commentaire