非阻塞 Websockets C++ 奇怪的延迟

Posted

技术标签:

【中文标题】非阻塞 Websockets C++ 奇怪的延迟【英文标题】:Nonblocking Winsockets c++ strange delays 【发布时间】:2012-04-01 15:45:07 【问题描述】:

我正在将在线游戏从 Linux 移植到 Windows。在 Linux 上一切正常,但在 Windows 上我有一些奇怪的行为。客户端和服务器通过恒定的 TCP 连接进行通信。服务器每 0.5 秒发送一次数据包。在 Linux 上,我每 0.5 秒接收一次数据包,但在 Windows 上,我有这样的东西:0.9,0.3,0.3,0.3,0.9 等等(间隔实际上取决于对服务器的 ping 间隔可能类似于 0.7,0.2 ,0.7)。 我使用非阻塞套接字。我尝试禁用 tcp nagle 算法。

这是一些客户的代码:

memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
int iStatus = getaddrinfo(Settings->GetDnSAddr().c_str(),
 Settings->GetPortStr().c_str(), &hints, &servinfo);
if(iStatus != 0 || servinfo == NULL)

    iState = L_CONNECT_DOWN;
    throw ExeptionNetwork(903,__FILE__,__LINE__,iStatus);
    return 0;


iSocketFD = socket(servinfo->ai_family,servinfo->ai_socktype,servinfo->ai_protocol);
if (iSocketFD == INVALID_SOCKET)

    THROWNETWORK(901);


cout<<"Connecting to server:"<<Settings->GetIPv4Addr()<<":"<<Settings->GetPort()<<endl;
if (connect(iSocketFD,servinfo->ai_addr,servinfo->ai_addrlen) == SOCKET_ERROR)

    cout<<"Connection failed:"<<errno<<endl;
    iState = L_CONNECT_DOWN;
    THROWNETWORK(902);
    return 0;

cout<<"Connected"<<endl;

#if (defined WIN32)||(defined WINCE)
unsigned long iMode = 1;
if (SOCKET_ERROR == ioctlsocket(iSocketFD, FIONBIO, &iMode))

    THROWNETWORK(903);

#else
fcntl(iSocketFD, F_SETFL, O_NONBLOCK);
#endif


char flag =1;
setsockopt(iSocketFD, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));

然后阅读我用 recv() 偷看,如果有什么要阅读的,我阅读。

有什么想法吗? 可能与经常调用 recv 有某种联系吗?我正在考虑将网络代码分离到单独的线程中,这可能会有所帮助...

【问题讨论】:

【参考方案1】:

使用非阻塞套接字时,不要使用recv() 来查看字节以查找数据。数据可用时使用select()WSAAsyncSelect()WSAAsyncEvent() 收到通知,然后调用recv() 进行读取。

【讨论】:

我已经尝试使用 select 和 WSAPoll() 来检查是否有要读取的数据,但没有帮助。 那你没有正确使用它们。请出示您的实际阅读代码。

以上是关于非阻塞 Websockets C++ 奇怪的延迟的主要内容,如果未能解决你的问题,请参考以下文章

windows下在非阻塞TCP套接字上使用SO_SNDBUF的奇怪行为

术语,概念

C++:如何测量非阻塞套接字的实际上传速率

具有非阻塞架构的 Python Web 服务器选项

如何以非阻塞、不可中断的方式从类中运行 C++ 函数 [关闭]

在 Windows 中创建 C++ 非阻塞计时器