1

I've got two systems, both running Windows 7. The source is 192.168.0.87, the target is 192.168.0.22, they are both connected to a small switch on my desk.

The source is transmitting a burst of 100 UDP packets to the target with this program -

#include <iostream>
#include <vector>

using namespace std;

#include <winsock2.h>


int main()
{
    // It's windows, we need this.
    WSAData wsaData;
    int wres = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (wres != 0) { exit(1); }

    SOCKET s = socket(AF_INET, SOCK_DGRAM, 0);
    if (s < 0) { exit(1); }

    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port = htons(0);

    if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { exit(3); }

    int max = 100;

    // build all the packets to send
    typedef vector<unsigned char> ByteArray;
    vector<ByteArray> v;
    v.reserve(max);
    for(int i=0;i<max;i++) {
        ByteArray bytes(150+(i%25), 'a'+(i%26));
        v.push_back(bytes);
    }

    // send all the packets out, one right after the other.
    addr.sin_addr.s_addr = htonl(0xC0A80016);// 192.168.0.22
    addr.sin_port = htons(24105);

    for(int i=0;i<max;++i) {
        if (sendto(s, (const char *)v[i].data(), v[i].size(), 0,
                   (struct sockaddr *)&addr, sizeof(addr)) < 0) {
            cout << "i: " << i << " error: " << errno;
        }
    }

    closesocket(s);

    cout << "Complete!" << endl;
}

Now, on first run I get massive losses of UDP packets (often only 1 will get through!). On subsequent runs, all 100 make it through. If I wait for 2 minutes or so, and run again, I'm back to losing most of the packets.

Reception on the target system is done using Wireshark. I also ran Wireshark at the same time on the source system, and found exactly the same trace as on the target in all cases.

That means that the packets are getting lost on the source machine, rather than being lost in the switch or on the wire.

I also tried running sysinternals process monitor, and found that indeed, all 100 sendto calls do result in appropriate winsock calls, but not necessarily in packets on the wire.

As near as I can tell (using arp -a), in all cases the target's IP is in the source's arp cache.

Can anyone tell me why Windows is so inconsistent in how it treats these packets? I get that in my actual application I've just got to rate limit my sends a bit, but I'd like to understand why it works sometimes and not others.

Oh yes, and I also tried swapping the systems for send and receive, with no change in behavior.

Michael Kohne
  • 11,888
  • 3
  • 47
  • 79
  • I have run into something similar. In my case an application that seems to run fine with Windows XP is having problems with Windows 7 due to dropped UDP packets/messages. What I am seeing is the client sends a request message to the server which receives it and sends an acknowledgement of the request before sending the actual response. The client never sees the acknowledgement however it does see the server response message which follows. How did your investigation turn out for you? – Richard Chambers Oct 15 '15 at 12:20
  • @RichardChambers - I never found out what what was going on for sure. I ended up with slight rate limiting on the source system, which worked for my application. – Michael Kohne Oct 15 '15 at 12:24
  • I just found [recv has no time to receive all the udp packets from a socket on win 7](http://stackoverflow.com/questions/8079614/recv-has-no-time-to-receive-all-the-udp-packets-from-a-socket-on-win-7) that has a comment about using the `setsockopt()` function to increase the network buffer size under Windows 7. I am going to try that out today and see what happens. – Richard Chambers Oct 15 '15 at 12:26

1 Answers1

0

Most probably the client is overruning udp send buffer. Maybe while ARP protocol is running to get the target MAC address. You say that you lose datagrams the first run and if you wait 2 minutes or more. Why don't you check with Wireshark what happens in that first run? (If ARP frames are sent/received)

If that is the problem, you could apply one of these 2 alternatives:

1-Before running make sure the ARP entry is there.

2-Send the first datagram, wait 1 sec or less, send the burst

rodolk
  • 5,606
  • 3
  • 28
  • 34