PDA

View Full Version : QUdpSocket error



mdecandia
24th October 2007, 14:34
Hi all,
I've done a client-server application to send data between two nodes. If I use both applications on linux machines, everything works fine.
When I recompile the client app on Windows platform, UDP datagram is sent correctly by windows client (I monitor network traffic by Ethereal but I don't know if it is really what network adapter sends) but very often server application doesn't receive entire datagram: It looses some IP packet (UDP datagram is fragmented in more than one IP packet because data is bigger than 1,5Kb).
I think there is some Windows network problem because server runs correctly with linux client.

Somebody may help me?

Thanks

Michele

DeepDiver
24th October 2007, 15:58
http://en.wikipedia.org/wiki/User_Datagram_Protocol


...
UDP does not guarantee reliability or ordering in the way that TCP does. Datagrams may arrive out of order, appear duplicated, or go missing without notice.
...


As you see: the behavior you describe is according to the definition of UDP.

In case you need reliability: you TCP.

Good luck,

Tom

mdecandia
24th October 2007, 16:32
Thank you but I know what is UDP.
My client/server application was developed to run in LAN context. I haven't any problem on Linux client so I don't understand why Windows must be a problem.

jpn
24th October 2007, 16:53
Just curious, may we see the code which reads data on the server side?

DeepDiver
24th October 2007, 16:56
Can you past some code to see what you do?

In this case I can have a closer look.

Nevertheless from my point of view: due to UDP nature there is nothing you can do against losing packets.
In a linux-linux environment you are simply lucky due to implementation and setup of drivers, module and network subsystem implementation.
I assume in a windows-windows environment you will be as lucky as in the linux-linux environment.

Tom

mdecandia
25th October 2007, 09:14
The client code follows:


QByteArray message;

..
// filling up message
..

QUdpSocket udpSocket;
udpSocket.writeDatagram(message.data(), message.size(), address,port);


The server code is


..
QUdpSocket udpSocket;
connect(&udpSocket, SIGNAL(readyRead()),
this, SLOT(processPendingDatagrams()),Qt::DirectConnecti on);

...

void Receiver::processPendingDatagrams()
{
while (udpSocket.hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(udpSocket.pendingDatagramSize());
udpSocket.readDatagram(datagram.data(), datagram.size());

}
}

I paste you the different output of ethereal on server with linux client:


No. Time Source Destination Protocol Info
..
3 0.004583 192.168.32.2 192.168.32.11 UDP Source port: 50259 Destination port: wizard
4 0.074725 192.168.32.11 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=0) [Reassembled in #17]
5 0.074845 192.168.32.11 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=1480) [Reassembled in #17]
6 0.074969 192.168.32.11 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=2960) [Reassembled in #17]
7 0.075092 192.168.32.11 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=4440) [Reassembled in #17]
8 0.075215 192.168.32.11 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=5920) [Reassembled in #17]
9 0.075338 192.168.32.11 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=7400) [Reassembled in #17]
10 0.075461 192.168.32.11 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=8880) [Reassembled in #17]
11 0.075583 192.168.32.11 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=10360) [Reassembled in #17]
12 0.075707 192.168.32.11 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=11840) [Reassembled in #17]
13 0.075830 192.168.32.11 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=13320) [Reassembled in #17]
14 0.075953 192.168.32.11 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=14800) [Reassembled in #17]
15 0.076076 192.168.32.11 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=16280) [Reassembled in #17]
16 0.076199 192.168.32.11 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=17760) [Reassembled in #17]
17 0.076258 192.168.32.11 192.168.32.2 UDP Source port: 33747 Destination port: 35147
..

and windows client:



No. Time Source Destination Protocol Info
..
7 17.149508 192.168.32.2 192.168.32.12 UDP Source port: 50146 Destination port: wizard
8 17.196854 192.168.32.12 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=0)
9 17.196978 192.168.32.12 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=1480)
10 17.197100 192.168.32.12 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=2960)
11 17.197223 192.168.32.12 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=4440)
12 17.197346 192.168.32.12 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=5920)
13 17.197469 192.168.32.12 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=7400)
14 17.197592 192.168.32.12 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=13320)
15 17.197715 192.168.32.12 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=23680)
16 17.197845 192.168.32.12 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=25160)
17 17.197969 192.168.32.12 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=26640)
18 17.198091 192.168.32.12 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=28120)
19 17.198214 192.168.32.12 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=29600)
20 17.198288 192.168.32.12 192.168.32.2 IP Fragmented IP protocol (proto=UDP 0x11, off=31080)
..


As you can see in windows case, many IP fragments were loosed.

DeepDiver
25th October 2007, 09:34
What is the return value of writeDatagram and readDatagram?
In general: you shall take care about return values - they have a meaning.

Here is the Qt documentation on writeDatagram:
Datagrams are always written as one block. The maximum size of a datagram is highly platform-dependent, but can be as low as 8192 bytes. If the datagram is too large, this function will return -1 and error() will return DatagramTooLargeError.

Sending datagrams larger than 512 bytes is in general disadvised, as even if they are sent successfully, they are likely to be fragmented by the IP layer before arriving at their final destination.

Believe it or not: ip packet loss is part of udp - if you need reliability: use tcp.

mdecandia
25th October 2007, 10:18
I take care of return values and they are about 20000 (bytes) on writeDatagram on linux and windows client.
Server receives that data size only when linux client is running. processPendingDatagram slot is not called when windows client is running becauese readyRead() signal is not emitted (Udp datagram isn't received entirely).

DeepDiver
25th October 2007, 10:47
MTU (http://en.wikipedia.org/wiki/Maximum_transmission_unit) on Ethernet is ~1500 bytes.
Meaning the IP packets have a max size of 1500 bytes.
In case you send data bigger than the MTU - you will get fragmentation.

This is what we see from your ethereal trace.

UDP doesn't take care about ordering of packet delivery and/or guarantee of delivery.

This is what we see in your ethereal trace as well.

As soon as one ip fragment is lost - the whole datagram is gone.

My advice: try TCP or send the 20000 bytes in chunks of less than 1480 bytes and re-assemble the whole data pack on server side on your own.

And believe me: not loosing data in the linux-linux setup is pure luck.