Ich muss einen Socket in einem Multithread-Linux-TCP-Server implementieren, der nach einem Timeout mit zwei Setsockopt, die mit SO_RCVTIMEO und SO_SNDTIMEO eingestellt sind, trennt.Recv gibt 0 statt -1 zurück, wenn Client abstürzt
Hier ist der Code:
if(setsockopt(receive_sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout))<0){
printf("errore sock option rcvtimeo\n");
exit(EXIT_FAILURE);
}
if(setsockopt(receive_sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout))<0){
printf("errore sock option sndtimeo\n");
exit(EXIT_FAILURE);
}
Nach dem Laichen des Fadens mit dieser Buchse verbunden ist, bleibt der Server in recv mit dieser Funktion:
int receive_message(int descriptor, char* buffer){
memset(buffer,0,sizeof(buffer));
int ret;
while((ret= recv(descriptor, buffer, BUFFER_SIZE-1, MSG_NOSIGNAL))<=0){
if (errno == EWOULDBLOCK || errno == EPIPE){
//stuff...
pthread_exit(NULL);
}
else if (errno == EINTR) continue;
else exit(EXIT_FAILURE);
}
buffer[ret]= '\0';
return ret;
}
Wenn die Client-Online bleibt aber ohne Antworten, wird es korrekt mit der Anweisung if (errno == EWOULDBLOCK || errno == EPIPE) beendet, aber wenn der Client abstürzt oder beendet wird, ist der ret-Wert aus dem receive für immer in der while-Schleife 0 anstatt - 1 oder EWOULDBLOCK.
Wie kann ich das beheben?
Auf '0' prüfen und damit umgehen? Von der man-Seite: * "Für TCP-Sockets bedeutet der Rückgabewert 0, dass der Peer seine halbe Seite der Verbindung geschlossen hat." * – user3386109
Ich dachte, dass der recv beim Absturz des Clients -1 zurückgibt. Meine Schuld, danke! – gabrielication
BTW: 'memset (Puffer, 0, sizeof (Puffer));' ist Cargocult Programmierung. Und errno ist nur nützlich, nachdem recv() -1 zurückgibt. Wenn recv()> = 0 zurückgegeben wird, hat errno keinen Bedeutungswert. – wildplasser