Nagle under Windows XP RRS feed

  • Question

  • Hi,

    I'm having problems getting the Nagle algorithm to work under WinXP (and Win2K), but it seems fine under Win7. I've written a simple program to test this as shown below.

    Basically, it opens a TCP connection to a hardware device at IP address - port 1002. Then it deliberatly calls send() 1000 times sending 4 bytes at a time. I then monitor what happens 'on the wire' using Wireshark.

    Under Win7, Windows coalesses these multiple calls into larger internet packets correctly - per the Nagle spec such that there is only one ethernet packet "in-flight" at any one time.

    However, under WinXP and Win2K I get storms of very short packets - each typically 8 or 12 bytes long. So windows is merging some packets together, but it isn't following Nagle because its sending several tens of internet packets before the first ACK comes back from the other end. These packets are separated by only 4 or 5 microseconds on the wire.

    Everything i've read on the web says all versions of Windows (since NT4 at least) enable Nagle by default. Most web articles are about how to turn Nagle off for gaming. I've tried setsocketopt() with TCP_NODelay, but nothing seems to change the behaviour. I've searched my registry for keys which may be affecting this, but can't find anything.

    So - any ideas what's going wrong? Can I get XP to correctly implement Nagle?




    #include "stdafx.h"

    int main(int argc, char* argv[])
      WSADATA     m_wsaData;
      SOCKET      m_Socket;
      sockaddr_in m_SockAddr;

      DWORD  nRet;
      int    i;

       // Try to start the windows socket support
      if (WSAStartup(MAKEWORD(2,1),&m_wsaData) != 0)
        {return (1);}

      // Try to create an IP Socket
      if (m_Socket == INVALID_SOCKET)
        {return (-1);}

      memset(&m_SockAddr, 0, sizeof(m_SockAddr));
      m_SockAddr.sin_addr.S_un.S_addr = 0x6802A8C0;  //
      m_SockAddr.sin_family           = AF_INET;
      m_SockAddr.sin_port             = htons(1002); // Port 1002

      if (connect(m_Socket, (sockaddr*)&m_SockAddr, sizeof(m_SockAddr) ))
        {return (WSAGetLastError());} 

      char stNetCmd[] = {0x00,0x00,0x04,0x00};

      for (i = 0; i < 1000; i++) {
        nRet = send( m_Socket, stNetCmd, sizeof(stNetCmd), 0 );

      return (0);



    Thursday, June 13, 2013 12:11 PM

All replies

  • Hi,

    to get help optimizing the code, you better turn to the msdn forums. http://social.msdn.microsoft.com/Forums/en-US/categories

    Also chek http://support.microsoft.com/kb/214397/en-us which indicates an application should attempt coallescing data and not rely on winsock to do everyting.

    As far as I know, winsock performance is dependend on the nic driver and settings. It might be worth tryin another driver or even nic, and see if the issue still occurs.


    Friday, June 14, 2013 9:39 AM
  • Thanks,

    Yes, i'm aware an applicaton should attempt to coalless, but i'm only responsible for the device driver and API DLL. The users write their own code and I can't control what they do. Also legacy stuff has to be supported. I suppose I'll have to start cacheing the send() requests in my DLL and/or driver.

    We have now verified the behaviour on several machines using different NIC's. They all behave correctly under Win7, and all fail under Win2K and WinXP. So I dom't think it's a NIC or driver problem, seems to be the WinXP TCP stack which I think is TCPIP.SYS.

    This appears to be a bug in the Windows XP TCPIP implementation of Nagle, which is why I'm asking here.



    Friday, June 14, 2013 9:46 AM
  • Hi,

    i would still recommend to turn to msdn to find other developers which might be experienced in this particular field. Here on technet, it are mostly infrastructure guys answering.

    One thing I can confirm: the windows TCP/Ip stack was heavily revised when Vista/2008 was released. Vista and up do have significant improvements.http://technet.microsoft.com/en-us/network/bb545475.aspx


    Friday, June 14, 2013 10:16 AM