Anda harus menggunakan langkah-langkah berikut untuk koneksi asinkron:
- buat soket dengan
socket(..., SOCK_NONBLOCK, ...)
- mulai koneksi dengan
connect(fd, ...)
- jika nilai kembalian bukan
0
maupunEINPROGRESS
, lalu batalkan dengan kesalahan - tunggu sampai
fd
ditandai sebagai siap untuk keluaran - periksa status soket dengan
getsockopt(fd, SOL_SOCKET, SO_ERROR, ...)
- selesai
Tanpa perulangan - kecuali jika Anda ingin menangani EINTR
.
Jika klien dimulai terlebih dahulu, Anda akan melihat kesalahan ECONNREFUSED
di langkah terakhir. Jika ini terjadi, tutup soket dan mulai dari awal.
Sulit untuk mengetahui apa yang salah dengan kode Anda, tanpa melihat detail lebih lanjut. Saya kira, Anda tidak membatalkan kesalahan di check_socket
Anda operasi.
Ada beberapa cara untuk menguji apakah koneksi nonblocking berhasil.
- panggil getpeername() terlebih dahulu, jika gagal dengan error ENOTCONN, koneksi gagal. lalu panggil getockopt dengan SO_ERROR untuk mendapatkan kesalahan tertunda pada soket
- panggil read dengan panjang 0. jika read gagal, koneksi gagal, dan errno for read mengindikasikan mengapa koneksi gagal; read mengembalikan 0 jika koneksi berhasil
- panggil terhubung lagi; jika errno adalah EISCONN, koneksi sudah terhubung dan koneksi pertama berhasil.
Referensi:Pemrograman Jaringan UNIX V1
D. J. Bernstein mengumpulkan berbagai metode untuk memeriksa apakah connect()
asinkron panggilan berhasil atau tidak. Banyak dari metode ini yang memiliki kelemahan pada sistem tertentu, jadi menulis kode portabel untuk itu tidak terduga sulit. Jika ada yang ingin membaca semua kemungkinan metode dan kelemahannya, lihat dokumen ini.
Bagi yang hanya menginginkan versi tl;dr, cara yang paling portable adalah sebagai berikut:
Setelah sistem menandai soket sebagai dapat ditulisi, pertama-tama panggil getpeername()
untuk melihat apakah itu terhubung atau tidak. Jika panggilan itu berhasil, soket tersambung dan Anda dapat mulai menggunakannya. Jika panggilan itu gagal dengan ENOTCONN
, koneksi gagal. Untuk mengetahui mengapa gagal, coba baca satu byte dari soket read(fd, &ch, 1)
, yang akan gagal juga tetapi kesalahan yang Anda dapatkan adalah kesalahan yang akan Anda dapatkan dari connect()
jika bukan non-pemblokiran.