Sto provando a verificare un socket chiuso che è stato chiuso con grazia dal peer senza incorrere nel colpo di latenza di una doppia mandata per indurre uno SIGPIPE
.Test per una presa chiusa
Uno dei presupposti qui è che il socket in caso di chiusura è stato chiuso con grazia dal peer subito dopo l'ultima scrittura/invio. Gli errori reali come una chiusura prematura vengono trattati altrove nel codice.
Se il socket è ancora aperto, ci saranno 0 o più dati byte che non voglio ancora estrarre dal buffer socket.
Stavo pensando che potrei chiamare int ret = recv(sockfd, buf, 1, MSG_DONTWAIT | MSG_PEEK);
per determinare se il socket è ancora connesso. Se è collegato ma non ci sono dati nel buffer, ricevo un ritorno di -1
con errno == EAGAIN
e restituisco il sockfd per il riutilizzo. Se è stato chiuso con grazia dal peer, otterrò ret == 0
e aprirò una nuova connessione.
Ho provato questo e si sembra al lavoro. Tuttavia, ho il sospetto che ci sia una piccola finestra tra quando ricevo l'ultimo bit dei miei dati e quando arriva il peer FIN
in cui posso ottenere un falso positivo EAGAIN
dal mio test recv
.
Questo mi morde o esiste un modo migliore per farlo?
Un modo alternativo è select() (o poll()), dal momento che può controllare un fd sia per leggere che per scrivere, ma non so se effettivamente risolve il problema relativo alla temporizzazione FIN. –
@Giuseppe: No, non penso che la selezione risolverebbe il problema dei tempi. –