Saya telah menulis program kecil yang berinteraksi dengan server di port tertentu. Program ini berfungsi dengan baik, tetapi:
Setelah program berhenti tiba-tiba, dan sejak koneksi soket ditampilkan dalam CLOSE_WAIT
status. Jika saya mencoba menjalankan program, program itu hang dan saya harus memaksanya menutup, yang mengakumulasi lebih banyak CLOSE_WAIT
koneksi soket.
Apakah ada cara untuk menghilangkan koneksi ini?
Jawaban:
CLOSE_WAIT
berarti program Anda masih berjalan, dan belum menutup soket (dan kernel sedang menunggu untuk melakukannya). Tambahkan-p
kenetstat
untuk mendapatkan pid, dan kemudian matikan dengan lebih kuat (denganSIGKILL
jika diperlukan). Itu harus menyingkirkanCLOSE_WAIT
soket Anda . Anda juga dapat menggunakanps
untuk menemukan pid.SO_REUSEADDR
untuk server danTIME_WAIT
soket, jadi tidak berlaku di sini.sumber
Seperti yang dijelaskan oleh Crist Clark .
sumber
close()
atauclosesocket()
, tergantung pada platform mana yang Anda gunakan.Saya juga mengalami masalah yang sama dengan server Tomcat terbaru (7.0.40). Ini menjadi non-responsif sekali selama beberapa hari.
Untuk melihat koneksi terbuka, Anda dapat menggunakan:
Seperti yang disebutkan dalam posting ini , Anda dapat menggunakan
/proc/sys/net/ipv4/tcp_keepalive_time
untuk melihat nilainya. Nilainya tampaknya dalam hitungan detik dan default ke 7200 (yaitu 2 jam).Untuk mengubahnya, Anda perlu mengedit
/etc/sysctl.conf
.sumber
Meskipun terlalu banyak koneksi CLOSE_WAIT berarti ada yang salah dengan kode Anda pada awalnya dan ini diterima sebagai praktik yang tidak baik.
Anda mungkin ingin memeriksa: https://github.com/rghose/kill-close-wait-connections
Apa yang dilakukan skrip ini adalah mengirimkan ACK yang telah ditunggu oleh koneksi.
Inilah yang berhasil bagi saya.
sumber
Harus disebutkan bahwa
Socket
instance di klien dan ujung server perlu dipanggil secara eksplisitclose()
. Jika hanya salah satu ujung yang dipanggilclose()
, soket akan tetap dalam status CLOSE_WAIT.sumber
Anda dapat menutup soket secara paksa dengan
ss
perintah; yangss
perintah adalah alat yang digunakan untuk membuang statistik socket dan menampilkan informasi dalam cara yang sama (meskipun sederhana dan lebih cepat) untuk netstat.Untuk mematikan soket apa pun dalam status CLOSE_WAIT, jalankan ini (sebagai root)
sumber
Perlu juga dicatat bahwa jika program Anda memunculkan proses baru, proses itu mungkin mewarisi semua pegangan yang Anda buka. Bahkan setelah program closs Anda sendiri, pegangan yang diwariskan itu masih bisa hidup melalui proses anak yatim piatu. Dan mereka tidak selalu muncul sama di netstat. Tapi tetap saja, soket akan tetap berada di CLOSE_WAIT saat proses anak ini hidup.
Saya memiliki kasus di mana saya menjalankan ADB. ADB sendiri memunculkan proses server jika belum berjalan. Ini mewarisi semua pegangan saya pada awalnya, tetapi tidak muncul sebagai memiliki salah satu dari mereka ketika saya menyelidiki (hal yang sama berlaku untuk macOS dan Windows - tidak yakin tentang Linux).
sumber