繁体   English   中英

Windows TCP套接字recv延迟

[英]Windows TCP socket recv delay

外部控制器每30ms通过TCP / IP套接字发送120字节的消息。 应用程序通过标准的tcp / ip socket recv函数接收此消息。 它在Linux和OSX下完美运行(recv每30ms返回120个字节的消息)。 在Windows下,recv大约每1秒返回~3500字节缓冲区。 其余的时间它返回0.在Windows下的Wireshark显示确实每隔30ms发送一次消息。

如何让windows tcp socket正常工作(没有延迟)?

PS:我已经玩过TCP_NODELAY和TcpAckFrequency。 Wireshark显示一切正常。 所以我认为这是一些Windows优化,应该关闭。

读 -

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;
}

初始化-

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;
}

考虑禁用Nagle算法。 120字节非常小,可能在发送之前缓冲数据。 我认为是Nagle算法的另一个原因是大约33次发送应该在1秒内发生。 这相当于33*120 = 3960 bytes / sec非常类似于您所看到的3500。

如下更改dataread函数,以便仅在出现错误时调用WSAGetLastError。

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;
}

您每毫秒轮询套接字的事实可能与您的性能问题有关。 但是我想在结束那个问题之前看看CheckSocket的来源。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM