2012-04-01 8 views
0

Ich portiere Online-Spiel von Linux zu Windows. Unter Linux funktioniert alles super, aber unter Windows habe ich seltsames Verhalten. Client und Server kommunizieren über eine konstante TCP-Verbindung. Der Server sendet das Paket alle 0,5 Sekunden. Und unter Linux empfange ich Paket alle 0,5 Sekunden, aber auf Windows habe ich etwas wie folgt: 0.9,0.3,0.3,0.3,0.9 und so weiter (Das Intervall hängt tatsächlich vom Ping zum Server-Intervall ab, kann etwa 0,7,0,2 sein , 0,7). Ich benutze nicht blockierende Sockets. Ich habe versucht, tcp nagle Algorithmus zu deaktivieren.Nonblocking WinSockets C++ seltsame Verzögerungen

Hier einige Code des Kunden:

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

Dann mit recv() i Peek zu lesen und wenn es etwas, was ich lesen zu lesen.

Irgendwelche Ideen? Kann es irgendwie sein, recv zu oft anzurufen? Ich denke über die Trennung von Netzwerk-Code auf den separaten Thread vielleicht wird es helfen ...

Antwort

2

Bei der Arbeit mit nicht-blockierenden Sockets, verwenden Sie nicht recv(), um Bytes auf der Suche nach Daten peek. Verwenden Sie select(), WSAAsyncSelect() oder WSAAsyncEvent(), um benachrichtigt zu werden, wenn Daten verfügbar sind, und rufen Sie recv() an, um es zu lesen.

+0

Ich habe bereits versucht, mit Select und WSAPoll() zu überprüfen, ob einige Daten gelesen werden, aber es hat nicht geholfen. – Rulk

+0

Dann verwenden Sie sie nicht richtig. Bitte zeigen Sie Ihren aktuellen Lesecode. –