Cara paksa dekat soket di TIME_WAIT?

Saya menjalankan program tertentu pada linux yang kadang-kadang crash. Jika anda membukanya dengan cepat setelah itu, mendengarkan pada soket 49201 bukan 49200 seperti itu pertama kalinya. netstat mengungkapkan bahwa 49200 di TIME_WAIT negara.

Ada sebuah program yang dapat anda jalankan untuk segera kekuatan soket itu bergerak keluar dari TIME_WAIT negara?

Mengomentari pertanyaan (1)
Larutan
/etc/init.d/networking restart

Biarkan saya menjelaskan. Transmission Control Protocol (TCP) adalah dirancang untuk menjadi dua arah, memerintahkan, dan dapat diandalkan data protokol transmisi antara dua end point (program). Dalam konteks ini, istilah yang dapat diandalkan, yang berarti bahwa itu akan memancarkan kembali paket-paket jika itu hilang di tengah. TCP menjamin keandalan dengan mengirimkan kembali Pengakuan (ACK) paket untuk satu atau berbagai paket-paket yang diterima dari teman sebaya.

Ini berlaku sama untuk sinyal-sinyal kontrol seperti penghentian permintaan/respon. RFC 793 mendefinisikan negara MENUNGGU WAKTU untuk menjadi sebagai berikut:

WAKTU-MENUNGGU - mewakili menunggu cukup waktu untuk lulus untuk memastikan remote TCP menerima pengakuan dari sambungan permintaan penghentian.

Lihat berikut TCP state diagram:

TCP adalah protokol komunikasi dua arah, sehingga ketika koneksi didirikan, tidak ada perbedaan antara client dan server. Juga, salah satu dapat menghubungi berhenti, dan kedua rekan kebutuhan untuk menyepakati penutupan untuk sepenuhnya menutup didirikan sebuah koneksi TCP.

Let's call yang pertama untuk memanggil berhenti sebagai aktif lebih dekat, dan peer lain yang pasif lebih dekat. Ketika aktif lebih dekat mengirimkan FIN, negara pergi ke SIRIP-MENUNGGU-1. Kemudian ia menerima sebuah ACK untuk dikirim FIN dan negara pergi ke SIRIP-TUNGGU-2. Setelah menerima FIN juga dari pasif lebih dekat, aktif lebih dekat mengirimkan ACK ke SIRIP dan negara berlaku untuk WAKTU-TUNGGU. Dalam kasus pasif lebih dekat tidak menerima ACK untuk kedua SIRIP, itu akan memancarkan kembali paket FIN.

RFC 793 set TIME-OUT untuk menjadi dua kali Maksimum Segmen Seumur hidup, atau 2MSL. Sejak MSL, waktu maksimum paket yang dapat berkeliaran di Internet, diatur untuk 2 menit, 2MSL adalah 4 menit. Karena tidak ada ACK ACK, aktif lebih dekat bisa't melakukan apa-apa selain menunggu 4 menit jika mematuhi protokol TCP/IP dengan benar, hanya dalam kasus pasif pengirim tidak menerima ACK untuk FIN (secara teoritis).

Dalam kenyataan, paket yang hilang adalah mungkin langka, dan sangat langka jika itu's semua yang terjadi dalam LAN atau dalam satu mesin.

Untuk menjawab pertanyaan verbatim, Bagaimana paksa * menutup soket di TIME_WAIT?, Saya masih akan tetap asli saya menjawab:

/etc/init.d/networking restart

Praktis berbicara, aku akan program itu sehingga mengabaikan WAKTU-MENUNGGU negara menggunakan SO_REUSEADDR pilihan sebagai WMR disebutkan. Apa sebenarnya SO_REUSEADDR lakukan?

soket Ini pilihan memberitahu kernel bahwa bahkan jika port ini sibuk (dalam TIME_WAIT negara), pergi ke depan dan reuse itu pula. Jika sibuk, tapi dengan negara lain, anda masih akan mendapatkan sebuah alamat yang sudah di gunakan kesalahan. Ini ini berguna jika server anda telah menutup ke bawah, dan kemudian restart segera sementara soket yang masih aktif di port. Anda harus menyadari bahwa jika setiap data yang tak terduga datang, mungkin membingungkan server anda, tapi sementara ini mungkin, itu tidak mungkin.

Komentar (5)

Saya don't know jika anda memiliki kode sumber dari program tertentu anda'kembali berjalan, tapi jika demikian anda bisa mengatur SO_REUSEADDR melalui setsockopt(2) yang memungkinkan anda untuk mengikat pada lokal anda, bahkan jika soket di TIME_WAIT negara (kecuali bahwa socket secara aktif mendengarkan, melihat socket(7)).

Untuk informasi lebih lanjut tentang negara TIME_WAIT melihat Unix socket FAQ.

Komentar (5)

Sejauh yang saya tahu tidak ada cara untuk secara paksa menutup socket di luar menulis sebuah sinyal yang lebih baik handler ke dalam program anda, tapi ada /proc file yang mengontrol berapa lama waktu yang dibutuhkan. File

/proc/sys/net/ipv4/tcp_tw_recycle

dan anda dapat mengatur batas waktu 1 detik dengan melakukan hal ini:

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

Namun, di halaman ini berisi peringatan tentang kemungkinan masalah keandalan ketika menetapkan variabel ini.

Ada juga yang berhubungan dengan file

/proc/sys/net/ipv4/tcp_tw_reuse

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

Kebetulan, kernel dokumentasi memperingatkan anda untuk tidak mengubah salah satu dari nilai-nilai ini tanpa 'saran/permintaan dari para ahli teknis'. Yang saya tidak.

Program ini harus telah menulis untuk mencoba mengikat ke port 49200 dan kemudian kenaikan sebesar 1 jika port tersebut sudah digunakan. Oleh karena itu, jika anda memiliki kontrol dari source code, anda bisa mengubah perilaku ini untuk menunggu beberapa detik dan mencoba lagi pada port yang sama, bukan incrementing.

Komentar (3)

Sebenarnya ada cara untuk membunuh sambungan - killcx. Mereka mengklaim ia bekerja dalam setiap keadaan koneksi (yang saya tidak terverifikasi). Perlu anda ketahui antarmuka di mana komunikasi terjadi meskipun, tampaknya menganggap eth0 secara default.

UPDATE: solusi lain adalah cutter yang datang di beberapa distro linux' repositori.

Komentar (0)

Pilihan lain adalah dengan menggunakan SO_LINGER pilihan dengan batas waktu dari 0. Dengan cara ini, ketika anda menutup soket ditutup secara paksa, mengirim RST bukannya pergi ke FIN/ACK penutupan perilaku. Ini akan menghindari TIME_WAIT negara, dan mungkin lebih tepat untuk beberapa kegunaan.

Komentar (4)

Alternatif solusi akan memiliki beberapa reliable proxy atau port forwarding software yang mendengarkan pada port 49200, kemudian meneruskan koneksi ke salah satu dari beberapa kasus anda kurang dapat diandalkan program menggunakan port yang berbeda... HAPROXY muncul dalam pikiran.

Kebetulan port anda menghubungkan pada cukup tinggi. Anda bisa mencoba menggunakan aplikasi yang tidak terpakai satu hanya di atas 0-1024 berbagai. Sistem anda kurang kemungkinan untuk menggunakan lebih rendah nomor port seperti port fana.

Komentar (0)

TIME_WAIT adalah masalah paling umum dalam soket pemrograman client server arsitektur. Tunggu beberapa detik mencoba secara berkala adalah solusi terbaik untuk itu. Untuk aplikasi real-time yang mereka butuhkan server harus segera bangkit Ada SO_REUSEADDR pilihan bagi mereka.

Komentar (0)