Today I've met an interesting problem with programming UDP sockets in C++. Generally UDP protocol just sends packets (datagrams) and doesn't care whether they are successfully delivered or not. They may be dropped or arrive out of order. Destination machine can even not read them or not exist at all! So I was sure that when I have a socket created with socket(), socktype=SOCK_DGRAM and connect(), I can then send packets using send() and expect this call will always be fast.
I was sure about that until today, when I met a case where a call to send() blocked for above 3 seconds! Then I've made some experiments. It looks like sending UDP packets from my Windows XP behaves like this:
I've found a question about this problem: "when does a udp sendto() blocks ?" at StackOverflow. It looks like this behavior is caused by the system unsuccessfully trying to resolve IP address to physical MAC address with every send. But it's highly operating system dependent so we can't do much about it. We just have to keep in mind that using blocking sockets for sending UDP packets can freeze our application or thread for even several seconds with each packet sent.
13 Sep 2011 Update: I researched this issue further and it looks like it's even more specific. If the target machine was online and contacted before, but now it's offline, send() is very quick. Only if the ARP forgets the IP-MAC pair for that machine, send() blocks for such a long time with every call. It probably happens after several hours. You can also force ARP to clear the cache by issuing following console command in Windows, as Administrator:
arp -d *.