2012-04-01 125 views
0

我將從Linux到Linux的在線遊戲移植到windows。在Linux上一切都很好,但在Windows上我有一些奇怪的行爲。客戶端和服務器通過不斷的TCP連接通信。服務器每0.5秒發送一次數據包。在Linux上,我每0.5秒接收一次數據包,但是在窗口中我有這樣的內容:0.9,0.3,0.3,0.3,0.9等等(間隔實際上取決於對服務器間隔的ping可能是類似於0.7,0.2 0.7)。 我使用非阻塞套接字。我試過禁用tcp nagle算法。非阻塞Winsockets C++奇怪的延遲

下面是一些客戶端的代碼:

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?我正在考慮將網絡代碼分離到單獨的線程,也許它會幫助...

回答

2

使用非阻塞套接字時,請勿使用recv()來查看查找數據的字節。當數據變爲可用時,使用select(),WSAAsyncSelect()WSAAsyncEvent(),然後調用recv()來讀取它。

+0

我已經嘗試過使用select和WSAPoll()來檢查是否有一些數據要讀取,但它沒有幫助。 – Rulk 2012-04-01 18:58:10

+0

然後你沒有正確使用它們。請顯示您的實際閱讀代碼。 – 2012-04-02 18:48:15