2010-11-11 5 views
0

Je viens compilé ce code: http://www.win32developer.com/tutorial/winsock/winsock_tutorial_2.shtmWinsock recv() ne bloque pas

J'ai ajouté quelques codes il ne recv(), dans une boucle infinie. Mon problème, s'il n'y a pas de données à lire, ça ne bloque toujours pas.

Est-ce que je me trompe totalement si je pense que recv devrait bloquer dans mon cas?

Le code que j'ai ajouté est:

for(;;) 
{ 
    char buffer[1000]; 
    memset(buffer,0,999); 
    int inDataLength = recv(Socket,buffer,1000,0); 

    int nError=WSAGetLastError(); 
    if(nError!=WSAEWOULDBLOCK&&nError!=0) 
    { 
    std::cout<<"Winsock error code: "<<nError<<"\r\n"; 
    std::cout<<"Client disconnected!\r\n"; 

    // Shutdown our socket 
    shutdown(Socket,SD_SEND); 

    // Close our socket entirely 
    closesocket(Socket); 

    break; 
    } 
} 

Il est à la fin, après la ligne std::cout<<"Client connected!\r\n\r\n";. Je sais que j'ai copié ceci à partir d'un exemple "non bloquant", mais je ne pense pas que ce code devrait faire quelque chose de non bloquant vraiment, encore, ma boucle for fonctionne comme une folle!

+1

Pourriez-vous coller le code supplémentaire que vous avez écrit? – chrisaycock

+0

Utilisez-vous des appels WSAsync ...? – Rob

+0

Quel type de client avez-vous connecté à votre serveur? – chrisaycock

Répondre

1
if((nError == SOCKET_ERROR) || (nError == 0)) 
    WSAGetLastError(); 
else 
    ; // handle success 

Voilà comment il devrait ressembler, et non comment vous l'avez fait.

+0

Juste pour clarifier: 'WSAEWOULDBLOCK' est bon pour les sockets ** non-bloquantes **. Et, vous devriez vérifier WSAGetLastError() SEULEMENT si le code de retour était 'SOCKET_ERROR' (-1). – Poni

+0

@Rob: Comment nError obtient-il sa valeur alors si je n'utilise pas WSAGetLastError()? –

+0

@Poni: Désolé, je voulais dire Poni, pas Rob. –

5

recv devrait bloquer par défaut, sauf s'il y a une erreur de socket ou que vous avez explicitement défini le socket sur non-bloquant. Assurez-vous de vérifier la valeur de retour pour l'erreur. Pour plus d'informations, consultez l'article MSDN de Microsoft sur le recv.

2

La boucle ne vérifie pas les erreurs correctement. Il doit plutôt ressembler à ceci:

char buffer[1000]; 
int inDataLength; 

do 
    { 
    inDataLength = recv(Socket, buffer, sizeof(buffer), 0); 
    if (inDataLength > 0) 
     { 
     // inDataLength number of bytes were received, use buffer as needed... 
     continue; 
     } 

    if (inDataLength == 0) 
     { 
     std::cout << "Client disconnected!" << std::endl; 
     break; 
     } 

    int nError = WSAGetLastError(); 
    if (nError != WSAEWOULDBLOCK) 
     { 
     std::cout << "Winsock error code: " << nError << std::endl; 
     break; 
     } 

    // optionally call select() here to wait for the socket 
    // to receive data before calling recv() again... 
    /* 
    fd_set fd; 
    FD_ZERO(&fd); 
    FD_SET(Socket, &fd); 

    timeval tv; 
    tv.tv_sec = ...; 
    tv.tv_usec = ...; 

    nError = select(Socket+1, &fd, NULL, NULL, &tv); 
    if (nError == 0) 
     { 
     std::cout << "Timeout waiting for data" << std::endl; 
     break; 
     } 

    if (nError == SOCKET_ERROR) 
     { 
     nError = WSAGetLastError(); 
     std::cout << "Winsock error code: " << nError << std::endl; 
     break; 
     } 
    */ 
    } 
while (true); 

// Shutdown our socket 
shutdown(Socket, SD_SEND); 

// Close our socket entirely 
closesocket(Socket); 
Questions connexes