recv () ne bloque pas

J’ai 2 machines exécutant un simple serveur C TCP que j’ai écrit à des fins de test, 1 avec Fedora 16, l’autre avec Ubuntu 11.10. Ma machine Fedora fonctionne parfaitement mais sur la machine Ubuntu, recv () ne bloque pas. N’oubliez pas que ces machines exécutent le même code exact. Quelqu’un a déjà vu ça? Merci

int TcpSocket::ReadFromClient(int socket, char* buf, int len) { char *request = buf; int slen = len; int c = recv(socket, request, slen, 0); while((c > 0) && (request[c-1] != '\n')) { request += c; slen -= c; c = recv(socket, request, slen, 0); } if (c < 0) { return c; } else if(c == 0) { //Sending back an empty string buf[0] = '\0'; } return len-slen; } 

Il semble que l’intention de votre code soit d’arrêter la lecture quand un octet arrive. Si tel est le cas, vous devez lire le socket 1 octet à la fois au lieu d’utiliser la totalité de la taille du tampon, d’autant plus que vous ne contrôlez que le dernier octet du tampon au lieu de vérifier chaque octet reçu.

Vous devez également changer la logique de boucle pour appeler uniquement recv() à un endroit au lieu de deux. Votre implémentation actuelle appelle recv () avec slen=0 lorsque le tampon est épuisé, ce qui définit c=0 et annule le premier octet du tampon.

Essayez plutôt ceci:

 int TcpSocket::ReadFromClient(int socket, char* buf, int len) { int slen = len; char ch; while (len > 0) { int ret = recv(socket, &ch, 1, 0); if (ret > 0) { *buf = ch; ++buf; --len; if (ch == '\n') break; } else { if ((ret == 0) || (errno != EAGAIN)) return ret; fd_set readfd; FD_ZERO(&readfd); FD_SET(socket, &readfd); timeval tv; tv.tv_sec = 5; tv.tv_usec = 0; ret = select(socket+1, &readfd, NULL, NULL, &tv); if (ret < 0) return ret; if (ret == 0) { // timeout elapsed while waiting for data // do something if desired... } } } return slen - len; }