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é
0néEINPROGRESS, quindi interrompi con errore - aspetta fino a
fdviene 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.