TCP socket re-enable delay TCP TCP

An external controller sends a 120-byte message over a TCP / IP socket every 30 ms. The application receives these messages through the standard tcp / ip socket return function. It works fine under Linux and OSX (recv returns 120-byte messages every 30 ms). On Windows, recv returns a buffer of ~ 3500 bytes every 1 second. The rest of the time is returned 0. Wireshark under Windows shows messages that really go out every 30 ms.

How to make windows tcp socket work correctly (without delay)?

PS: I already played with TCP_NODELAY and TcpAckFrequency. Wireshark shows that everything is in order. Therefore, I believe that there are some Windows optimizations that should be disabled.

Reading -

int WMaster::DataRead(void) { if (!open_ok) return 0; if (!CheckSocket()) { PrintErrNo(); return 0; } iResult = recv(ConnectSocket, (char *)input_buff,sizeof(input_buff),0); nError=WSAGetLastError(); if(nError==0) return iResult; if(nError==WSAEWOULDBLOCK) return iResult; PrintErrNo(); return 0; } 

Initialization -

 ConnectSocket = INVALID_SOCKET; iResult = WSAStartup(MAKEWORD(2,2), &wsaData); ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); ZeroMemory(&clientService, sizeof(clientService)); clientService.sin_family = AF_INET; clientService.sin_addr.s_addr = inet_addr( deviceName.toLatin1().constData() ); clientService.sin_port = htons( port); iResult = setsockopt(ConnectSocket, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof (int)); u_long iMode=1; iResult=ioctlsocket(ConnectSocket,FIONBIO,&iMode); iResult = ::connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) ); 

CheckSocket -

 bool WMaster::CheckSocket(void) { socklen_t len = sizeof (int); int retval = getsockopt (ConnectSocket, SOL_SOCKET, SO_ERROR, (char*)(&valopt), &len ); if (retval!=0) { open_ok=false; return false; }; return true; } 
+4
source share
2 answers

Consider disabling the Nagle algorithm. 120 bytes are quite small and it is possible that the data is buffered before being sent. Another reason I think this is the Nagle algorithm is because about 33 shipments should happen in 1 second. This corresponds to 33*120 = 3960 bytes / sec , very close to the 3500 that you see.

+1
source

Modify your dataread function so that WSAGetLastError is raised only when an error occurs.

 int WMaster::DataRead(void) { if (!open_ok) return 0; if (!CheckSocket()) { PrintErrNo(); return 0; } iResult = recv(ConnectSocket, (char *)input_buff,sizeof(input_buff),0); if(iResult >= 0) { return iResult; } nError=WSAGetLastError(); if(nError==WSAEWOULDBLOCK) return iResult; PrintErrNo(); return 0; } 

The fact that you polled a socket every milliseconds may have something to do with your performance issue. But I would like to see the source in CheckSocket before concluding that this is a problem.

0
source

All Articles