• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 4259
  • Last Modified:

Windows 7 drops UDP packets when sent in rapid succession

I have a client application that needs to send 5 very short UDP packets in rapid succession. This has never been a problem with packet loss but since the advent of Windows 7 more often than not only the last packet reaches the NIC for transmission and all previous packets are lost. This is easily reproduced under Windows 7 X64 but also occurs under Windows 7 X86. Using the sample code included, one simply has to do a packet capture of packets to UDP port 123 using Wireshark to see that only one out of 5 packets are transmitted.

-      I realize that UDP transport is not guaranteed, but these are 5 small packets and this has never caused packet loss under XP or Vista. All packets at least make it to the NIC for transmission.

-      Introducing a Sleep(1) between sendto’s solves the problem, but given Windows’ low resolution timing this adds about a 15ms. delay between each send, which is way too long to meet my requirements.

-      It doesn’t matter is all sendto’s are to a single IP address or to 5 different IP addresses, only the last packet seems to make it through the stack.

-      There doesn’t seem to be any indication of failure from the non-blocking sendto.
Any ideas how this issue can be addressed? Without the ability to send more than 1 packet to multiple destinations in rapid sequence I can’t meet my application requirements.

#define WIN32_LEAN_AND_MEAN

#include <winsock2.h>
#include <stdio.h>

// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

int main()
{

	int iResult;
	WSADATA wsaData;

	SOCKET SendSocket = INVALID_SOCKET;
	sockaddr_in RecvAddr;

	unsigned short Port = 123;

	char SendBuf[32];
	int BufLen = sizeof(SendBuf);

	//----------------------
	// Initialize Winsock
	iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (iResult != NO_ERROR) {
		printf("WSAStartup failed with error: %d\n", iResult);
		return 1;
	}

	//---------------------------------------------
	// Create a socket for sending data
	SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (SendSocket == INVALID_SOCKET) {
		printf("socket failed with error: %ld\n", WSAGetLastError());
		WSACleanup();
		return 1;
	}
	//---------------------------------------------
	// Set up the RecvAddr structure with the IP address of
	// the receiver (in this example case "192.168.1.1")
	// and the specified port number.
	RecvAddr.sin_family = AF_INET;
	RecvAddr.sin_port = htons(Port);
	RecvAddr.sin_addr.s_addr = inet_addr("192.168.1.2");

	//---------------------------------------------
	// Send a datagram to the receiver
	printf("Sending a datagram to the receiver...\n");
	int i;
	for (i = 0; i < 5; i++) {
		memset(SendBuf, i, sizeof(SendBuf));
		iResult = sendto(SendSocket,
			SendBuf, BufLen, 0, (SOCKADDR *) & RecvAddr, sizeof (RecvAddr));
		if (iResult != BufLen) {
			printf("sendto failed with error: %d\n", WSAGetLastError());
			closesocket(SendSocket);
			WSACleanup();
			return 1;
		}
	}
	//---------------------------------------------
	// When the application is finished sending, close the socket.
	printf("Finished sending. Closing socket.\n");
	iResult = closesocket(SendSocket);
	if (iResult != 0) {
		printf("closesocket failed with error: %d\n", WSAGetLastError());
		WSACleanup();
		return 1;
	}
	//---------------------------------------------
	// Clean up and quit.
	printf("Exiting.\n");
	WSACleanup();
	return 0;
}

Open in new window

0
jcyr
Asked:
jcyr
  • 4
  • 4
1 Solution
 
pmasottaCommented:
try calling SendARP() pointing to your destination IP before calling sendto()
reed
0
 
jcyrAuthor Commented:
Looked promising but didn't work. The destination IP addresses are not on the local subnet and either sendARP or ResolveIpNetEntry2 fail with return code 0x43 and doesn't populate the ARP table. I would have expected it to return the gateway's MAC, but no such luck.

My bad for using 192.168 addresses in the sample code. The application in question needs to send to routable addresses.

Still losing packets,
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
pmasottaCommented:
1) try with a local address first in order to see if the problem is related to the ARP cache or not
2) when you want to send to external addresses try populating the ARP cache like this
SendARP(<defaultGategayIP>) ;
0
 
jcyrAuthor Commented:
I wanted to try that, but as of now I have no way to determine programatically what the gateway address IP might be for any given IP.
0
 
jcyrAuthor Commented:
Oh, and to answer your question. Yes the sendARP fixes the problem for IP adresses within the local subnet. Not for routed addresses.
0
 
pmasottaCommented:
jcyr:
your question is solved

now you can ask how to get the default gateway programatically or just read here ;-)
GetAdaptersInfo()
http://msdn.microsoft.com/en-us/library/aa365917(v=vs.85).aspx
0
 
jcyrAuthor Commented:
Great. ARPing the gateway did the trick.
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 4
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now