Saya tahu ada beberapa pertanyaan SE tentang ini, dan saya percaya saya membaca banyak dari mereka yang penting sebelum sampai ke titik ini.
Yang dimaksud dengan "sisi server TIME_WAIT
" yang saya maksud adalah keadaan pasangan soket sisi server yang memulai () di sisi server.
Saya sering melihat pernyataan-pernyataan ini yang kedengarannya bertentangan dengan saya:
- Sisi server
TIME_WAIT
tidak berbahaya - Anda harus merancang aplikasi jaringan Anda agar klien memulai close (), oleh karena itu klien harus
TIME_WAIT
Alasan saya menemukan kontradiksi ini adalah karena TIME_WAIT
pada klien dapat menjadi masalah - klien dapat kehabisan port yang tersedia, jadi pada dasarnya hal di atas merekomendasikan untuk memindahkan beban TIME_WAIT
ke sisi klien di mana itu bisa menjadi masalah, dari sisi server di mana itu bukan masalah.
Sisi klien TIME_WAIT
tentu saja hanya masalah untuk jumlah kasus penggunaan yang terbatas. Sebagian besar solusi client-server akan melibatkan satu server dan banyak klien, klien biasanya tidak berurusan dengan volume koneksi yang cukup tinggi untuk itu menjadi masalah, dan bahkan jika mereka melakukannya, ada sejumlah rekomendasi untuk "sehat" ( sebagai lawan SO_LINGER
dengan 0 timeout, atau campur tangan dengan tcp_tw sysctls) memerangi sisi klien TIME_WAIT
dengan menghindari membuat terlalu banyak koneksi terlalu cepat. Tapi itu tidak selalu layak, misalnya untuk kelas aplikasi seperti:
- sistem pemantauan
- memuat generator
- proksi
Di sisi lain, saya bahkan tidak mengerti bagaimana sisi server TIME_WAIT
sangat membantu. Alasannya TIME_WAIT
bahkan ada di sana, adalah karena itu mencegah menyuntikkan TCP
fragmen basi ke aliran mereka tidak lagi milik. Untuk sisi klien, TIME_WAIT
itu dicapai hanya dengan membuatnya tidak mungkin untuk membuat koneksi dengan ip:port
pasangan yang sama dengan yang dimiliki oleh koneksi basi ini (pasangan yang digunakan dikunci oleh TIME_WAIT
). Tetapi untuk sisi server, ini tidak dapat dicegah karena alamat lokal akan memiliki port penerima, dan selalu akan sama, dan server tidak bisa (AFAIK, saya hanya punya bukti empiris) menolak koneksi hanya karena rekan yang masuk akan membuat pasangan alamat yang sama yang sudah ada dalam tabel socket.
Saya memang menulis sebuah program yang menunjukkan bahwa TIME-WAIT sisi-server diabaikan. Selain itu, karena pengujian dilakukan pada 127.0.0.1, kernel harus memiliki bit khusus yang bahkan memberitahukannya apakah itu sisi server atau sisi klien (karena jika tidak tupel akan sama).
Sumber: http://pastebin.com/5PWjkjEf , diuji pada Fedora 22, konfigurasi net default.
$ gcc -o rtest rtest.c -lpthread
$ ./rtest 44400 s # will do server-side close
Will initiate server close
... iterates ~20 times successfully
^C
$ ss -a|grep 44400
tcp TIME-WAIT 0 0 127.0.0.1:44400 127.0.0.1:44401
$ ./rtest 44500 c # will do client-side close
Will initiate client close
... runs once and then
connecting...
connect: Cannot assign requested address
Jadi, untuk sisi server TIME_WAIT
, koneksi pada pasangan port yang persis sama dapat dibangun kembali dengan segera dan berhasil, dan untuk sisi klien TIME-WAIT
, pada iterasi kedua connect()
gagal dengan benar
Untuk meringkas, pertanyaannya adalah dua kali lipat:
- Apakah sisi server
TIME_WAIT
benar - benar tidak melakukan apa-apa, dan dibiarkan begitu saja karenaRFC
mengharuskannya? - Apakah alasan rekomendasi tersebut bagi klien untuk memulai close () karena server
TIME_WAIT
tidak berguna?
TIME_WAIT
.