close
panggilan hanya menandai soket TCP ditutup. Itu tidak dapat digunakan lagi oleh proses. Tetapi kernel mungkin masih menyimpan beberapa sumber daya untuk suatu periode (TIME_WAIT, 2MLS dll.).
Pengaturan SO_REUSEADDR harus menghilangkan masalah pengikatan.
Jadi pastikan nilai true
benar-benar bukan nol saat memanggil setsockopt
(bug luapan dapat menimpanya):
true = 1;
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(int))
Ada pid
variabel adalah kode Anda. Jika Anda menggunakan fork
(untuk memulai proses penanganan koneksi), maka Anda harus menutup sock
juga dalam proses yang tidak membutuhkannya.
Pertama untuk penamaan, jadi kita semua memberi nama yang sama:
Sisi server:
Soket diteruskan ke listen()
lalu ke accept()
sebut saja mendengarkan socket. Soket dikembalikan oleh accept()
sebut saja diterima soket.
Sisi klien:
Soket diteruskan ke connect()
sebut saja menghubungkan/terhubung soket.
Mengenai masalah Anda:
Untuk mengakhiri accept()
koneksi ed tutup diterima soket (apa yang Anda sebut terhubung) secara opsional terlebih dahulu menggunakan shutdown()
diikuti oleh close ()
.
Untuk kemudian menerima loop koneksi baru tepat sebelum panggilan ke accept()
, jangan buka bind()
dan listen()
lagi.
Hanya matikan dan tutup mendengarkan socket jika Anda ingin menyingkirkan pending connect()
s diterbitkan setelah accept()
dikembalikan.
Sambungan masih aktif karena Anda lupa menutup soket yang tersambung. Menutup soket pendengar tidak secara otomatis menutup soket yang tersambung.
//necessary code
close(connected); // <---- add this line
close(sock);
goto label;
Saya tidak yakin mengapa Anda mendapatkan EADDRINUSE. Kode bekerja dengan baik di linux dan mac os.