Pertanyaan Bagaimana cara menutup soket secara paksa dalam TIME_WAIT?


Saya menjalankan program tertentu di linux yang kadang-kadang crash. Jika Anda membukanya dengan cepat setelah itu, ia akan mendengarkan pada soket 49201 bukan 49200 seperti yang dilakukan pertama kali. netstat mengungkapkan bahwa 49200 dalam keadaan TIME_WAIT.

Apakah ada program yang dapat Anda jalankan untuk segera memaksa soket keluar dari negara TIME_WAIT?


109
2017-09-03 12:57




Jika Anda di sini karena "terlalu banyak TIME_WAIT di server ", hanya lewati tiga jawaban pertama yang menghindari pertanyaan alih-alih menjawabnya. - Pacerier


Jawaban:


/etc/init.d/networking restart

Biar saya jelaskan. Transmission Control Protocol (TCP) dirancang untuk menjadi protokol transmisi data dua arah, dipesan, dan dapat diandalkan antara dua titik akhir (program). Dalam konteks ini, istilah yang dapat diandalkan berarti bahwa ia akan mengirim kembali paket jika hilang di tengah. TCP menjamin keandalan dengan mengirimkan kembali paket Acknowledgement (ACK) kembali untuk satu atau berbagai paket yang diterima dari rekan.

Ini berlaku sama untuk sinyal kontrol seperti permintaan / respons penghentian. RFC 793 mendefinisikan status TIME-WAIT sebagai berikut:

TIME-WAIT - mewakili menunggu   waktu yang cukup untuk lulus untuk memastikan       TCP remote menerima pengakuan koneksi       permintaan penghentian.

Lihat diagram keadaan TCP berikut: alt text

TCP adalah protokol komunikasi dua arah, jadi ketika koneksi dibuat, tidak ada perbedaan antara klien dan server. Juga, salah satu dapat memanggil berhenti, dan kedua rekan perlu menyetujui penutupan untuk sepenuhnya menutup koneksi TCP yang ditetapkan.

Mari kita panggil yang pertama untuk memanggil berhenti sebagai aktif lebih dekat, dan yang lainnya mengintip pasif lebih dekat. Ketika jarak yang aktif mengirim FIN, negara pergi ke FIN-MENUNGGU-1. Kemudian menerima ACK untuk FIN yang dikirim dan negara pergi ke FIN-MENUNGGU-2. Setelah menerima FIN juga dari dekat pasif, aktif lebih dekat mengirim ACK ke FIN dan negara pergi ke TIME-TUNGGU. Dalam hal dekat pasif tidak menerima ACK ke FIN kedua, itu akan mengirimkan kembali paket FIN.

RFC 793 mengatur TIME-OUT menjadi dua kali Umur Segmen Maksimum, atau 2MSL. Karena MSL, waktu maksimum paket dapat berjalan di Internet, diatur ke 2 menit, 2MSL adalah 4 menit. Karena tidak ada ACK ke ACK, yang aktif lebih dekat tidak dapat melakukan apa-apa selain menunggu 4 menit jika menganut protokol TCP / IP dengan benar, hanya dalam kasus pengirim pasif belum menerima ACK ke FIN nya (secara teoritis) .

Pada kenyataannya, paket yang hilang mungkin langka, dan sangat jarang jika itu semua terjadi di dalam LAN atau di dalam satu mesin.

Untuk menjawab pertanyaan kata demi kata, Bagaimana caranya secara paksa tutup soket di TIME_WAIT ?, saya akan tetap menggunakan jawaban asli saya:

/etc/init.d/networking restart

Secara praktis, saya akan memprogramnya sehingga mengabaikan status TIME-WAIT menggunakan opsi SO_REUSEADDR seperti yang disebutkan WMR. Apa sebenarnya yang dilakukan SO_REUSEADDR?

Opsi soket ini memberitahu kernel   bahkan jika port ini sibuk (masuk
  status TIME_WAIT), lanjutkan dan   tetap menggunakannya kembali. Jika sibuk, tapi   dengan negara bagian lain, Anda masih akan mendapatkan   alamat sudah digunakan kesalahan. Saya t   berguna jika server Anda telah ditutup   down, dan kemudian restart segera   sementara soket masih aktif   Pelabuhan. Anda harus sadar bahwa jika   setiap data tak terduga masuk, mungkin   membingungkan server Anda, tetapi sementara ini   mungkin, itu tidak mungkin.


139
2017-09-03 13:11



Jawaban bagus, tapi bukan jawaban yang benar untuk pertanyaannya. Memulai kembali jaringan akan berfungsi, tetapi kemudian akan me-reboot, jadi ini tidak mungkin benar. - Chris Huang-Leaver
@Chris Huang-Leaver, pertanyaannya adalah "Apakah ada program yang dapat Anda jalankan untuk segera memaksa soket keluar dari negara TIME_WAIT?" jika reboot dapat dianggap menjalankan program, maka itu juga akan menjadi jawaban yang benar. Menurut Anda, mengapa ini tidak benar? - Eugene Yokota
WMR memiliki jawaban yang paling berguna (yang saya lakukan ketika saya mengalami masalah seperti ini). Memulai kembali jaringan terlalu drastis untuk menjadi solusi, dan bisa memakan waktu lebih lama daripada hanya menunggu waktu habis. Jawaban yang benar untuk pertanyaannya adalah 'Tidak', tetapi SO tidak akan membiarkan Anda mengetik dua jawaban huruf :-) - Chris Huang-Leaver
oh oke, lain kali beberapa proses tergantung pada SIGTERM saya hanya akan menghancurkan komputer saya daripada memperbaikinya. - Longpoke


Saya tidak tahu apakah Anda memiliki kode sumber dari program tertentu yang Anda jalankan, tetapi jika demikian Anda bisa mengatur SO_REUSEADDR melalui setsockopt(2) yang memungkinkan Anda untuk mengikat pada alamat lokal yang sama bahkan jika soket dalam keadaan TIME_WAIT (kecuali soket itu sedang mendengarkan secara aktif, lihat socket(7)).

Untuk informasi lebih lanjut tentang negara TIME_WAIT, lihat FAQ soket Unix.


50
2017-09-03 13:17



tetapi saya tidak mendapatkan kesalahan yang sudah terikat. ketika saya menjalankan program lagi itu mendengarkan dalam posting (123456) juga saya dapat melihat bahwa sistem menunjukkan TIME_WAIT untuk port itu tetapi masih saya dapat terhubung. Mengapa? - Jayapal Chandran
Bahkan dengan SO_REUSEADDR, masih mungkin untuk mendapatkan kesalahan "Alamat sudah digunakan". Untuk detail, lihat hea-www.harvard.edu/~fine/Tech/addrinuse.html. - Jingguo Yao
@WMR SO_REUSEADDR tidak "menutup" soket. Ini hanya memungkinkan Anda untuk menggunakan kembali yang sudah dibuka. Jadi pertanyaannya masih "Cara paksa menutup soket masuk TIME_WAIT? " - Pacerier


Sejauh yang saya tahu tidak ada cara untuk secara paksa menutup soket di luar menulis pengatur sinyal yang lebih baik ke dalam program Anda, tetapi ada file / proc yang mengontrol berapa lama waktu habis. File itu

/proc/sys/net/ipv4/tcp_tw_recycle

dan Anda dapat mengatur batas waktu hingga 1 detik dengan melakukan ini:

echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle 

Namun, halaman ini berisi peringatan tentang kemungkinan masalah keandalan saat mengatur variabel ini.

Ada juga file yang terkait

/proc/sys/net/ipv4/tcp_tw_reuse

yang mengontrol apakah soket TIME_WAIT dapat digunakan kembali (mungkin tanpa batas waktu).

Kebetulan, dokumentasi kernel memperingatkan Anda untuk tidak mengubah salah satu dari nilai-nilai ini tanpa 'saran / permintaan ahli teknis'. Saya tidak.

Program harus ditulis untuk mencoba mengikat ke port 49200 dan kemudian bertambah 1 jika port sudah digunakan. Oleh karena itu, jika Anda memiliki kontrol terhadap kode sumber, Anda dapat mengubah perilaku ini untuk menunggu beberapa detik dan coba lagi pada port yang sama, alih-alih menambah.


32
2017-09-03 13:24



pikir kedua dua contoh harus s / rw / tw / saya akan mengedit, tetapi tidak cukup rep.
Diambil dari dokumentasi kernel: Perhatian. Baik tcp_tw_recycle dan tcp_tw_reuse dapat menyebabkan masalah. Anda seharusnya tidak mengaktifkan baik tanpa memahami topologi jaringan di antara node (s) yang menggunakan atau digunakan oleh node di mana parameter diaktifkan. Koneksi yang pergi melalui node yang menyadari status koneksi TCP, seperti firewall, NAT atau load balancer dapat mulai menjatuhkan frame karena pengaturan. Masalahnya akan terlihat ketika ada jumlah koneksi yang cukup besar.
Menyetelnya ke 1 berfungsi untuk koneksi masa depan, tetapi bagaimana dengan yang saat ini yang sudah dibuka? - Pacerier


Sebenarnya ada cara untuk membunuh koneksi - killcx. Mereka mengklaim itu bekerja dalam keadaan koneksi (yang saya belum diverifikasi). Anda perlu mengetahui antarmuka di mana komunikasi terjadi, tampaknya mengasumsikan eth0 secara default.

UPDATE: solusi lain adalah pemotong yang ada di beberapa repositori distro linux.


16
2017-10-30 17:32



Terima kasih! Utilitas ini berfungsi dengan baik! Menyelamatkan saya dari keharusan untuk memulai kembali pekerjaan panjang. - Zanson


Pilihan lainnya adalah menggunakan opsi SO_LINGER dengan batas waktu 0. Dengan cara ini, ketika Anda menutup soket secara paksa tertutup, mengirim RST alih-alih masuk ke dalam perilaku penutupan FIN / ACK. Ini akan menghindari status TIME_WAIT, dan mungkin lebih sesuai untuk beberapa penggunaan.


3
2018-06-10 22:33



Ini juga kehilangan data keluar yang masih dalam perjalanan, dan dapat menyebabkan kesalahan di ujung lainnya. Tidak direkomendasikan. - user207421
@EJP Gagal lebih awal hampir selalu merupakan panggilan yang tepat. Jaringan tidak dapat diandalkan, dan perkelahian yang akan memperlambat segalanya. Aplikasi yang mogok tidak dapat mengasumsikan bahwa data apa pun berhasil keluar dengan aman. - Tobu
Sebenarnya, saya akan merekomendasikan ini setiap hari ketika endpoint yang lain adalah bus bus industri buggy, tertanam yang mengimplementasikan transport layer aplikasi sendiri yang dapat diandalkan melalui TCP, di mana kata transport mencegah koneksi dari pernah menutup kecuali menerima RST dan dengan demikian mengisi batas koneksi di gateway itu. Sana. Saya memberi Anda contoh yang sangat spesifik dan sangat nyata yang, sayangnya, mengharuskan beralih ke peretasan seperti ini. - andyn
@Tobu Networking tidak dapat diandalkan, tetapi TCP mencoba untuk, dan membuat yang lebih buruk bukan merupakan membuat sesuatu yang lebih baik, dan membiarkan TCP melakukan tugasnya tidak merupakan 'pertempuran' apa pun. - user207421


Sebuah solusi alternatif akan memiliki beberapa proksi yang dapat diandalkan atau perangkat lunak port forwarding yang mendengarkan pada port 49200, kemudian meneruskan koneksi ke salah satu dari beberapa contoh program Anda yang kurang dapat diandalkan menggunakan port yang berbeda ... HAPROXY muncul dalam pikiran.

Kebetulan port koneksi Anda cukup tinggi. Anda dapat mencoba menggunakan yang tidak terpakai tepat di atas rentang 0-1024. Sistem Anda cenderung menggunakan nomor port yang lebih rendah sebagai port efemeral.


2
2017-08-21 20:28





TIME_WAIT adalah masalah paling umum dalam arsitektur server klien pemrograman soket. Tunggu beberapa detik mencoba secara berkala adalah solusi terbaik untuk itu. Untuk aplikasi real time, mereka perlu server harus segera bangun Ada opsi SO_REUSEADDR untuk mereka.


0
2017-10-13 19:07