非阻塞Winsockets c ++奇怪的延迟

时间:2012-04-01 15:45:08

标签: c++ winapi visual-c++ winsock asyncsocket

我将在线游戏从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 个答案:

答案 0 :(得分:2)

使用非阻塞套接字时,请勿使用recv()查看查找数据的字节。当数据可用时,使用select()WSAAsyncSelect()WSAAsyncEvent()会收到通知,然后致电recv()进行阅读。