Dovresti utilizzare i seguenti passaggi per una connessione asincrona:
- crea un socket con
socket(..., SOCK_NONBLOCK, ...)
- avvia la connessione con
connect(fd, ...)
- se il valore restituito non è né
0
néEINPROGRESS
, quindi interrompi con errore - aspetta fino a
fd
viene segnalato come pronto per l'output - controlla lo stato del socket con
getsockopt(fd, SOL_SOCKET, SO_ERROR, ...)
- fatto
Nessun ciclo, a meno che tu non voglia gestire EINTR
.
Se il client viene avviato per primo, dovresti visualizzare l'errore ECONNREFUSED
nell'ultimo passaggio. Se ciò accade, chiudi il socket e ricomincia dall'inizio.
È difficile dire cosa c'è che non va nel tuo codice, senza vedere maggiori dettagli. Suppongo che tu non interrompa in caso di errori nel tuo check_socket
funzionamento.
Ci sono alcuni modi per verificare se una connessione non bloccante riesce.
- chiama prima getpeername(), se fallisce con errore ENOTCONN, la connessione fallisce. quindi chiama getsockopt con SO_ERROR per ottenere l'errore in sospeso sul socket
- chiama read con una lunghezza di 0. se la lettura è fallita, la connessione è fallita, e l'errno per read indica perché la connessione è fallita; read restituisce 0 se la connessione riesce
- chiama di nuovo la connessione; se l'errno è EISCONN, la connessione è già connessa e la prima connessione è riuscita.
Rif:UNIX Network Programming V1
D. J. Bernstein ha raccolto vari metodi per verificare se un connect()
asincrono chiamata riuscita o meno. Molti di questi metodi hanno degli svantaggi su alcuni sistemi, quindi scrivere codice portatile per questo è inaspettatamente difficile. Se qualcuno vuole leggere tutti i possibili metodi e i loro svantaggi, dai un'occhiata a questo documento.
Per coloro che vogliono solo la versione tl;dr, il modo più portabile è il seguente:
Una volta che il sistema segnala il socket come scrivibile, chiama prima getpeername()
per vedere se è connesso o meno. Se la chiamata è andata a buon fine, il socket si è connesso e puoi iniziare a usarlo. Se la chiamata fallisce con ENOTCONN
, la connessione non è riuscita. Per scoprire perché non è riuscito, prova a leggere un byte dal socket read(fd, &ch, 1)
, anche questo fallirà ma l'errore che ottieni è l'errore che avresti ottenuto da connect()
se non fosse non bloccante.