Struktur paket TCP (format pengepala segmen). Mari pecahkan rangkaian komputer: HTTP, TCP, REST

Mewujudkan sambungan TCP

Dalam protokol TCP, sambungan diwujudkan menggunakan "jabat tangan tiga kali ganda" yang diterangkan dalam bahagian Penubuhan Sambungan. Untuk mewujudkan sambungan, satu pihak (seperti pelayan) secara pasif menunggu sambungan masuk dengan melaksanakan primitif LISTEN dan ACCEPT, sama ada menyatakan sumber tertentu atau tidak menyatakannya.

Bahagian lain (seperti klien) mengeluarkan CONNECT primitif, menyatakan alamat IP dan port yang ingin disambungkan, saiz segmen TCP maksimum, dan secara pilihan beberapa data pengguna (seperti kata laluan). Primitif CONNECT menghantar segmen TCP dengan set bit SYN dan bit ACK dikosongkan dan menunggu respons.

Apabila segmen ini tiba di destinasinya, entiti TCP menyemak untuk melihat sama ada sebarang proses telah melaksanakan primitif LISTEN, menentukan sebagai parameter port yang sama yang terkandung dalam medan Port Destinasi. Jika tiada proses sedemikian, ia bertindak balas dengan menghantar segmen dengan bit RST ditetapkan untuk menolak sambungan.

Jika mana-mana proses sedang mendengar pada mana-mana port, maka segmen TCP masuk dihantar kepada proses tersebut. Yang terakhir boleh menerima sambungan atau menolaknya. Jika proses menerima sambungan, ia bertindak balas dengan pengakuan. Urutan segmen TCP yang dihantar dalam kes biasa (Gamb. a) Perhatikan bahawa segmen dengan set bit SYN menduduki 1 bait ruang nombor jujukan, yang mengelakkan kekaburan dalam pengakuan mereka.

Jika dua hos secara serentak cuba mewujudkan sambungan antara satu sama lain, maka urutan peristiwa yang berlaku akan sepadan dengan Rajah. b. Akibatnya, hanya satu sambungan akan diwujudkan, bukan dua, kerana sepasang titik akhir mengenal pasti sambungan secara unik. Iaitu, jika kedua-dua sambungan cuba mengenal pasti diri mereka menggunakan pasangan (x, y), hanya satu entri jadual dibuat untuk (x, y).

Nilai awal nombor jujukan sambungan bukan sifar atas sebab yang dibincangkan di atas. Satu litar berdasarkan pemasa digunakan, menukar keadaannya setiap 4 μs. Untuk kebolehpercayaan yang lebih tinggi, hos selepas kegagalan dilarang daripada but semula lebih awal daripada selepas jangka hayat paket maksimum telah berlalu. Ini memastikan bahawa tiada paket daripada sambungan terdahulu yang terapung di Internet.

Pengguguran Sambungan TCP

Walaupun sambungan TCP adalah dupleks penuh, untuk memahami cara ia dikeluarkan, adalah lebih baik untuk menganggapnya sebagai pasangan sambungan simpleks. Setiap sambungan simpleks terputus secara berasingan daripada rakan kongsinya. Untuk menutup sambungan, mana-mana pihak boleh menghantar segmen TCP dengan bit FIN ditetapkan kepada satu, menunjukkan bahawa ia tidak mempunyai data lagi untuk dihantar. Apabila segmen TCP ini menerima pengakuan, arah penghantaran ini ditutup. Walau bagaimanapun, data mungkin terus mengalir selama-lamanya dalam arah yang bertentangan. Sambungan terputus apabila kedua-dua arah ditutup. Biasanya, empat segmen TCP diperlukan untuk menutup sambungan: satu dengan bit FIN dan satu dengan bit ACK dalam setiap arah. Bit ACK pertama dan bit FIN kedua juga boleh terkandung dalam satu segmen TCP, yang akan mengurangkan bilangan segmen kepada tiga.

Sama seperti perbualan telefon di mana kedua-dua pihak boleh mengucapkan selamat tinggal dan menutup telefon pada masa yang sama, kedua-dua hujung sambungan TCP boleh menghantar mesej FIN pada masa yang sama. Mereka berdua menerima pengakuan biasa dan sambungan ditutup. Pada asasnya, tiada perbezaan antara pemutusan sambungan serentak dan berurutan.

Untuk mengelakkan masalah dua tentera, pemasa digunakan. Jika respons kepada segmen FIN yang dihantar tidak tiba dalam dua selang hayat paket maksimum, pengirim akan menutup sambungan. Pihak lain akhirnya akan menyedari bahawa tiada siapa yang menjawab dan juga akan memutuskan sambungan. Walaupun penyelesaian ini tidak ideal, memandangkan ketidakupayaan ideal, kita perlu menggunakan apa yang kita ada. Dalam amalan, masalah timbul agak jarang.

Kawalan Penghantaran TCP

Seperti yang dinyatakan sebelum ini, pengurusan tetingkap TCP tidak terikat secara langsung dengan pengakuan, seperti yang dilakukan dalam kebanyakan protokol pemindahan data. Sebagai contoh, katakan penerima mempunyai penimbal 4096-bait. Jika pengirim menghantar segmen 2048-bait yang berjaya diterima oleh penerima, maka penerima mengakui penerimaannya. Walau bagaimanapun, ini meninggalkan penerima dengan hanya 2048 bait ruang penimbal kosong (sehingga aplikasi mengambil beberapa data daripada penimbal), yang dilaporkan kepada pengirim, menunjukkan saiz tetingkap yang sesuai (2048) dan bilangan bait dijangka seterusnya.

Pengirim kemudian menghantar 2048 bait lagi, yang diakui, tetapi saiz tetingkap diisytiharkan sebagai 0. Pengirim mesti berhenti menghantar sehingga hos penerima membebaskan ruang penimbal dan meningkatkan saiz tetingkap.

Dengan saiz tetingkap sifar, pengirim tidak boleh menghantar segmen, kecuali dalam dua kes. Pertama, ia dibenarkan untuk menghantar data segera, contohnya supaya pengguna boleh mematikan proses yang berjalan pada mesin jauh. Kedua, pengirim boleh menghantar segmen 1-bait meminta penerima mengulangi maklumat tentang saiz tetingkap dan bait seterusnya yang dijangkakan. Piawaian TCP secara eksplisit menyediakan ciri ini untuk mengelakkan kebuntuan jika iklan saiz tetingkap hilang.

Pengirim tidak perlu menghantar data dengan segera kerana ia datang dari aplikasi. Selain itu, tiada siapa yang memerlukan penerima menghantar pengesahan secepat mungkin. Contohnya, entiti TCP, setelah menerima 2 KB pertama data daripada aplikasi dan mengetahuinya saiz yang tersedia tetingkap adalah 4 KB, saya betul-betul betul jika saya hanya menyimpan data yang diterima dalam penimbal sehingga 2 KB data lain tiba untuk memindahkan segmen dengan 4 KB muatan dengan segera. Kebijaksanaan ini boleh digunakan untuk meningkatkan prestasi.

Pertimbangkan sambungan TELNET dengan editor interaktif yang bertindak balas kepada setiap ketukan kekunci. Dalam kes yang paling teruk, apabila watak tiba di entiti TCP yang menghantar, ia mencipta segmen TCP 21-bait dan menghantarnya ke lapisan IP, yang seterusnya menghantar datagram IP 41-bait.

Pada penghujung penerima, entiti TCP segera bertindak balas dengan pengakuan 40 bait (20 bait pengepala TCP dan 20 bait pengepala IP). Kemudian, apabila editor membaca bait itu daripada penimbal, entiti TCP akan menghantar kemas kini pada saiz penimbal, mengalihkan tetingkap 1 bait ke kanan. Saiz paket ini juga 40 bait. Akhirnya, apabila editor telah memproses aksara ini, ia menghantar kembali gema, dihantar dalam paket 41-bait. Secara keseluruhan, untuk setiap aksara yang dimasukkan dari papan kekunci, empat paket dengan jumlah saiz 162 bait dihantar. Dalam keadaan kekurangan kapasiti talian, kaedah operasi ini tidak diingini.

Untuk memperbaiki keadaan, banyak pelaksanaan TCP menangguhkan pengakuan dan kemas kini saiz tetingkap sebanyak 500 ms dengan harapan untuk mendapatkan data tambahan untuk menghantar pengakuan dalam satu paket. Jika editor berjaya bergema dalam masa 500 ms, kepada pengguna jauh Hanya satu paket 41-bait perlu dihantar, sekali gus mengurangkan beban rangkaian kepada separuh.

Walaupun kaedah kelewatan ini mengurangkan beban rangkaian, kecekapan rangkaian penghantar kekal rendah kerana setiap bait dihantar dalam paket 41 bait yang berasingan. Kaedah yang meningkatkan kecekapan dikenali sebagai algoritma Nagle (Nagle, 1984). Cadangan Nagl kedengaran agak mudah: jika data sampai kepada pengirim satu bait pada satu masa, pengirim hanya menghantar bait pertama dan menampan selebihnya sehingga pengakuan bait pertama diterima. Selepas ini, anda boleh menghantar semua aksara yang terkumpul dalam penimbal sebagai satu segmen TCP dan mula menimbal semula sehingga anda menerima pengesahan aksara yang dihantar. Jika pengguna memasukkan aksara dengan cepat dan rangkaian adalah perlahan, maka sejumlah besar aksara akan dihantar dalam setiap segmen, sekali gus mengurangkan beban pada rangkaian dengan ketara. Di samping itu, algoritma ini membenarkan paket baharu dihantar walaupun bilangan aksara dalam penimbal melebihi separuh saiz tetingkap atau saiz segmen maksimum.

Algoritma Nagl digunakan secara meluas oleh pelbagai pelaksanaan protokol TCP, tetapi kadangkala terdapat situasi di mana lebih baik untuk melumpuhkannya. Khususnya, apabila bekerja Aplikasi X-Windows di Internet, maklumat tentang pergerakan tetikus dihantar ke komputer jauh. (X-Window ialah sistem pengurusan tetingkap untuk kebanyakan sistem pengendalian jenis UNIX). Jika anda menimbal data ini untuk pemindahan kelompok, kursor akan bergerak secara tersentak-sentak dengan jeda yang lama, akibatnya ia akan menjadi sangat sukar, hampir mustahil, untuk menggunakan program ini.

Satu lagi masalah yang boleh merendahkan prestasi TCP dengan ketara dikenali sebagai sindrom tingkap bodoh (Clark, 1982). Intipati masalahnya ialah data dihantar oleh entiti TCP dalam blok besar, tetapi bahagian penerima aplikasi interaktif membacanya aksara demi aksara.

Mari lihat contoh - keadaan awal adalah seperti berikut: penimbal TCP bahagian penerima penuh, dan pengirim mengetahui ini (iaitu, saiz tetingkapnya ialah 0). Kemudian aplikasi interaktif membaca satu aksara daripada aliran TCP. Entiti TCP yang menerima dengan gembira memberitahu pengirim bahawa saiz tetingkap telah meningkat dan ia kini boleh menghantar 1 bait. Pengirim mematuhi dan menghantar 1 bait. Penampan penuh lagi, yang penerima maklumkan dengan menghantar pengakuan untuk segmen 1-bait dengan saiz tetingkap sifar. Dan ini boleh berterusan selama-lamanya.

David Clark mencadangkan menghalang hujung penerima daripada menghantar maklumat saiz tetingkap satu bait. Sebaliknya, penerima mesti menunggu sehingga terdapat sejumlah besar ruang kosong dalam penimbal. Khususnya, penerima MESTI tidak menghantar maklumat tentang saiz tetingkap baharu sehingga ia boleh menerima segmen saiz maksimum yang diiklankan semasa membuat sambungan, atau penimbalnya sekurang-kurangnya separuh percuma.

Di samping itu, pengirim itu sendiri boleh membantu meningkatkan kecekapan penghantaran dengan tidak menghantar segmen yang terlalu kecil. Sebaliknya, ia mesti menunggu sehingga saiz tetingkap cukup besar untuk membolehkannya menghantar segmen penuh atau sekurang-kurangnya sama dengan separuh saiz penimbal penerima. (Penghantar boleh menganggarkan saiz ini daripada jujukan mesej saiz tetingkap yang telah diterima sebelum ini.)

Dalam masalah menghilangkan sindrom tingkap bodoh, algoritma Nagl dan penyelesaian Clark saling melengkapi. Nagl cuba menyelesaikan masalah aplikasi yang menyediakan data kepada watak entiti TCP mengikut aksara. Clark cuba menyelesaikan masalah aplikasi yang menerima aksara data mengikut aksara daripada TCP. Kedua-dua penyelesaian adalah baik dan boleh berfungsi serentak. Intipati mereka adalah untuk tidak menghantar atau meminta untuk memindahkan data dalam bahagian yang terlalu kecil.

Entiti penerima TCP boleh pergi lebih jauh dalam meningkatkan prestasi dengan hanya mengemas kini maklumat saiz tetingkap dalam ketulan besar. Seperti entiti TCP yang menghantar, ia juga boleh menimbal data dan menyekat permintaan READ daripada aplikasi sehingga ia mempunyai jumlah data yang besar. Ini mengurangkan bilangan panggilan kepada entiti TCP dan seterusnya mengurangkan overhed. Sudah tentu, pendekatan ini meningkatkan masa tindak balas, tetapi untuk aplikasi bukan interaktif, seperti pemindahan fail, mengurangkan masa yang dihabiskan untuk keseluruhan operasi adalah lebih penting daripada meningkatkan masa tindak balas untuk permintaan individu.

Masalah penerima lain ialah segmen yang diterima dalam susunan yang salah. Ia boleh disimpan atau dibuang mengikut budi bicara penerima. Sudah tentu, pengakuan hanya boleh dihantar jika semua data sehingga bait yang diakui telah diterima. Jika penerima menerima segmen O, 1, 2, 4, 5, 6, dan 7, ia boleh mengakui penerimaan data sehingga bait terakhir segmen 2. Apabila pengirim tamat masa, ia akan menghantar segmen 3 semula. Jika penerima mempunyai segmen 4 hingga 7 yang ditimbal oleh segmen masa 3 tiba, ia boleh mengakui penerimaan semua bait sehingga bait terakhir segmen 7.

- 1

Menggunakan program yang menganalisis trafik dan protokol yang digunakan - Wireshark, anda boleh memerhatikan operasi jabat tangan TCP tiga peringkat:


Langkah 1

Pelanggan TCP memulakan jabat tangan tiga hala dengan menghantar segmen dengan set bendera cek SYN(Segerakkan Nombor Jujukan) dengan menyatakan nilai asal dalam medan nombor jujukan dalam pengepala. Ini ialah nilai awal nombor turutan, dikenali sebagai Nombor Urutan Mula ( ISN), dipilih secara rawak dan digunakan untuk mula menjejaki aliran data daripada klien ke pelayan untuk sesi tersebut. ISN dalam pengepala setiap segmen ditambah satu untuk setiap bait data yang dihantar dari klien ke pelayan sementara pertukaran data diteruskan.

Rajah menunjukkan bagaimana output penganalisis protokol menunjukkan bendera kawalan SYN dan nombor urutan relatif.

Bendera kawalan SYN ditetapkan dan nombor urutan relatif ialah 0. Walaupun graf penganalisis protokol menunjukkan nilai relatif untuk nombor urutan dan pengakuan, nilai sebenar ialah nombor 32-bit binari. Kita boleh menentukan nombor sebenar yang dihantar dalam pengepala segmen dengan memeriksa kawasan "Packet Bytes". Di sini anda boleh melihat empat bait yang diwakili dalam perenambelasan bentuk.

Langkah 2

Pelayan TCP mesti mengakui penerimaan segmen SYN daripada klien untuk mewujudkan sesi daripada klien ke pelayan. Untuk melakukan ini, pelayan menghantar segmen kembali kepada klien dengan set bendera ACK, menunjukkan bahawa medan nombor pengakuan didayakan. Dengan bendera ini ditetapkan pada segmen, pelanggan mengiktiraf ini sebagai pengakuan bahawa pelayan telah menerima SYN daripada TCP pelanggan.

Pengepala UDP sentiasa 64 bit panjang. Medan yang ditakrifkan dalam segmen UDP (lihat rajah) termasuk yang berikut:
1. Port sumber: nombor port sumber (16 bit)
2. Port destinasi: Nombor port destinasi (16 bit)
3. Panjang Mesej: Panjang pengepala UDP dan data UDP (16 bit)
4. Jumlah semak: jumlah semak yang dikira bagi tajuk dan medan data (16 bit)
5. Data: data protokol lapisan atas (ULP) (panjang pembolehubah)
Contoh protokol yang menggunakan UDP: TFTP, SNMP, Rangkaian Sistem fail(NFS) dan Nama domain Sistem (DNS).

Pengepala TCP mengandungi maklumat yang ditakrifkan protokol TCP ohm DALAM bahagian ini Komponen pengepala TCP diterangkan.

Segmen TCP dihantar menggunakan paket IP. Pengepala TCP mengikut pengepala IP. Pemisahan ini membolehkan kewujudan protokol peringkat hos lain selain daripada TCP. Medan pengepala TCP termasuk yang berikut:

Port sumber: Nombor port sumber (16 bit)

Port destinasi: Nombor port destinasi (16 bit)

Nombor urutan: nombor siri oktet pertama data
segmen yang digunakan untuk memastikan data masuk disusun dengan betul
(32 bit)

Nombor pengakuan: oktet dijangka seterusnya
TCP (32 bit)

Panjang pengepala: Bilangan perkataan 32-bit dalam pengepala (4 bit)

Terpelihara: Tetapkan kepada 0 (3 bit)

Bit kawalan: Fungsi kawalan seperti tetapan,
beban lampau dan penamatan sesi (9 bit). Satu bit yang mempunyai istimewa
nilai yang sering dianggap sebagai bendera.

Tetingkap: bilangan oktet yang sanggup diterima oleh peranti (16 bit)

Checksum: Jumlah semak yang dikira bagi pengepala dan
data (16 bit)

Urgent: Menunjukkan penghujung data mendesak (16 bit)

Pilihan: Pada masa ini satu pilihan ditakrifkan - saiz maksimum
Segmen TCP (0 atau 32 bit)

Data: data protokol lapisan atas (ULP).
(panjang berubah-ubah)

pengenalan

TCP ialah protokol berorientasikan sambungan. Sebelum mana-mana pihak boleh menghantar data kepada yang lain, sambungan mesti diwujudkan antara mereka. Dalam bab ini, kita akan melihat secara terperinci bagaimana sambungan TCP diwujudkan dan cara ia ditamatkan.

Oleh kerana TCP memerlukan sambungan diwujudkan antara dua hujung untuk beroperasi, ia berbeza daripada protokol tanpa sambungan seperti UDP. Kami melihat bahawa apabila menggunakan UDP, setiap pihak hanya menghantar datagram kepada yang lain tanpa terlebih dahulu membuat sambungan.

Mewujudkan dan menamatkan sambungan

Untuk melihat apa yang berlaku apabila sambungan TCP diwujudkan dan ditamatkan, kami melaksanakan arahan berikut pada sistem svr4:

svr4% telnet bsdi buang
Mencuba 192.82.148.3 ...
Bersambung ke bsdi.
Watak melarikan diri ialah "^]".
^] masukkan Kawalan, kurungan segi empat tepat,
telnet> berhenti untuk meminta pelanggan Telnet menutup sambungan
Sambungan ditutup.

Perintah telnet mewujudkan sambungan TCP ke hos bsdi pada port yang sepadan dengan perkhidmatan buang (Bab 1, bahagian). Ini adalah jenis perkhidmatan yang kita perlukan untuk melihat apa yang berlaku apabila sambungan diwujudkan dan terputus, tetapi tanpa menukar data.

output tcpdump

Rajah 18.1 menunjukkan output tcpdump untuk segmen yang dijana oleh arahan ini.

1 0.0 svr4.1037 > bsdi.discard: S 1415531521:1415531521 (0)
menang 4096
2 0.002402 (0.0024) bsdi.discard > svr4.1037: S 1823083521:1823083521 (0)
ack 1415531522 menang 4096

3 0.007224 (0.0048) svr4.1037 > bsdi.buang: . ack 1823083522 menang 4096
4 4.155441 (4.1482) svr4.1037 > bsdi.buang: F 1415531522:1415531522 (0)
ack 1823083522 menang 4096
5 4.156747 (0.0013) bsdi.discard > svr4.1037: . ack 1415531523 menang 4096
6 4.158144 (0.0014) bsdi.discard > svr4.1037: F 1823083522:1823083522 (0)
ack 1415531523 menang 4096
7 4.180662 (0.0225) svr4.1037 > bsdi.buang: . ack 1823083523 menang 4096

Rajah 18.1 output tcpdump untuk mewujudkan dan meruntuhkan sambungan TCP.

Tujuh segmen TCP ini hanya mengandungi pengepala TCP. Tiada pertukaran data.

Untuk segmen TCP, setiap baris keluaran bermula dengan

sumber > destinasi: bendera

dengan bendera ialah empat daripada enam bit bendera pengepala TCP (). Rajah 18.2 menunjukkan lima simbol berbeza yang sepadan dengan bendera dan mungkin muncul dalam output.

3 aksara singkatan

Penerangan

nombor turutan penyegerakan
penghantar telah selesai menghantar data
set semula sambungan
menghantar data ke proses penerimaan secepat mungkin
tiada satu pun daripada empat bendera ditetapkan

Rajah 18.2 Keluarkan aksara bendera oleh tcpdump untuk bit bendera dalam pengepala TCP.

Dalam contoh ini kita melihat bendera S, F dan titik. Dua lagi bendera (R dan P) akan muncul kemudian. Dua bit bendera yang lain dalam pengepala TCP - ACK dan URG - dicetak oleh arahan tcpdump.

Lebih daripada satu daripada empat bit bendera yang ditunjukkan dalam Rajah 18.2 mungkin terdapat dalam satu segmen, namun, biasanya hanya satu bendera ditetapkan.

RFC 1025 [Postel 1987] merujuk kepada segmen di mana gabungan maksimum semua bit bendera yang tersedia ditetapkan secara serentak (SYN, URG, PSH, FIN dan 1 bait data) sebagai paket Kamikaze (dalam Bahasa Inggeris Terdapat beberapa definisi lain bagi pakej yang serupa, iaitu "pakej kotor", "pakej pokok Tahun Baru", dll.).

Dalam baris 1, medan 1415531521:1415531521 (0) bermakna nombor jujukan paket ialah 1415531521 dan bilangan bait data dalam segmen ialah 0. Perintah tcpdump mencetak nombor jujukan permulaan, titik bertindih, nombor jujukan tamat anggaran, dan kemudian bilangan bait data dalam kurungan. Adalah mungkin untuk melihat nombor jujukan akhir yang dijangkakan apabila bilangan bait lebih besar daripada 0. Medan muncul (1) jika segmen mengandungi satu atau lebih bait data pengguna, atau (2) jika bendera SYN, FIN atau RST. Dalam baris 1, 2, 4, dan 6 dalam Rajah 18.1, medan ini muncul kerana bit bendera ditetapkan—tiada data ditukar dalam contoh ini.

Dalam baris 2, medan ack 1415531522 mengandungi nombor pengesahan. Ia dicetak hanya jika bendera ACK ditetapkan. Medan win 4096 pada setiap baris output menunjukkan saiz tetingkap yang diisytiharkan oleh pengirim. Dalam contoh ini, apabila tiada komunikasi, saiz tetingkap dibiarkan tidak berubah dan nilai lalai 4096 telah digunakan. (Kami akan merangkumi saiz tetingkap TCP dalam bahagian dalam Bab 20.)

Dan medan terakhir dalam output dalam Rajah 18.1, menunjukkan saiz segmen maksimum (MSS - saiz segmen maksimum), pilihan yang ditetapkan oleh pengirim. Pengirim tidak mahu menerima segmen TCP yang lebih besar daripada nilai ini. Ini biasanya dilakukan untuk mengelakkan pemecahan (Bab 11, bahagian). Kami akan merangkumi saiz segmen maksimum dalam bahagian bab ini dan menunjukkan format pelbagai pilihan TCP dalam bahagian bab ini.

Gambar rajah masa

Rajah 18.3 menunjukkan rajah pemasaan yang sepadan dengan pertukaran paket ini. (Kami menerangkan beberapa ciri asas gambar rajah pemasaan apabila kami mula-mula melihat .) Angka ini menunjukkan bahagian mana yang menghantar paket. Juga ditunjukkan ialah output arahan tcpdump (ia mencetak SYN dan bukannya S). Gambar rajah masa ini telah mengalih keluar nilai saiz tetingkap kerana ia tidak berkaitan dengan perbincangan kami.

Protokol Penubuhan Sambungan

Sekarang mari kita kembali kepada butiran protokol TCP, yang ditunjukkan dalam Rajah 18.3. Untuk mewujudkan sambungan TCP, anda mesti:

  1. Peminta (biasanya dipanggil klien) menghantar segmen SYN yang menunjukkan nombor port pelayan yang ingin disambungkan oleh klien dan nombor urutan asal pelanggan (dalam contoh ini, ISN, 1415531521). Ini adalah segmen nombor 1.
  2. Pelayan bertindak balas dengan segmen SYNnya yang mengandungi nombor urutan asal pelayan (segmen 2). Pelayan juga mengakui ketibaan SYN pelanggan menggunakan ACK (ISN pelanggan tambah satu). Nombor urutan tunggal digunakan setiap SYN.
  3. Pelanggan mesti mengakui ketibaan SYN dari pelayan menggunakan ACK (pelayan ISN tambah satu, segmen 3).

Tiga segmen ini cukup untuk mewujudkan sambungan. Ini sering dipanggil jabat tangan tiga hala.

Rajah 18.3 Gambarajah pemasaan penubuhan dan penamatan sambungan.

Pihak yang menghantar SYN pertama dianggap telah mengaktifkan sambungan (aktif terbuka). Bahagian lain, yang menerima SYN pertama dan menghantar SYN seterusnya, mengambil bahagian pasif dalam membuka sambungan (pasif terbuka). (Dalam bahagian dalam bab ini, kami akan memperincikan prosedur untuk membuka sambungan, di mana kedua-dua pihak dianggap aktif apabila sambungan diwujudkan.)

Apabila setiap pihak telah menghantar SYNnya untuk mewujudkan sambungan, ia memilih Nombor Urutan Permulaan (ISN) untuk sambungan itu. ISN mesti berubah setiap kali, jadi setiap sambungan mempunyai ISN sendiri yang berbeza. RFC 793 [Postel 1981c] menyatakan bahawa ISN ialah pembilang 32-bit yang bertambah satu setiap 4 mikrosaat. Terima kasih kepada nombor jujukan, paket yang tinggal di rangkaian dan dihantar kemudian tidak dianggap sebagai sebahagian daripada sambungan sedia ada.

Bagaimanakah nombor urutan dipilih? Dalam 4.4BSD (dan kebanyakan pelaksanaan Berkeley), nombor jujukan awal ditetapkan kepada 1 apabila sistem dimulakan. Amalan yang serupa dikutuk oleh Keperluan Hos RFC. Nilai ini kemudiannya meningkat sebanyak 64000 setiap setengah saat dan kembali kepada 0 setiap 9.5 jam. (Ini sepadan dengan pembilang yang meningkat sebanyak satu setiap 8 mikrosaat, bukannya setiap 4 mikrosaat.) Selain itu, setiap kali sambungan diwujudkan, pembolehubah ini dinaikkan sebanyak 64000.

Jurang 4.1 saat antara segmen 3 dan 4 sepadan dengan masa antara membuat sambungan dan memasukkan perintah berhenti telnet untuk menamatkan sambungan.

Putuskan sambungan Protokol

Untuk mewujudkan sambungan, 3 segmen diperlukan, dan untuk memecahkannya - 4. Ini dijelaskan oleh fakta bahawa sambungan TCP boleh berada dalam keadaan separuh tertutup. Oleh kerana sambungan TCP adalah dupleks penuh (data boleh bergerak dalam setiap arah secara bebas daripada arah yang lain), setiap arah mesti ditutup secara berasingan daripada yang lain. Peraturannya ialah setiap pihak mesti menghantar FIN apabila pemindahan data selesai. Apabila TCP menerima FIN, ia mesti memberitahu aplikasi bahawa pihak jauh sedang meruntuhkan sambungan dan berhenti menghantar data ke arah itu. FIN biasanya dihantar akibat permohonan ditutup.

Kita boleh mengatakan bahawa bahagian yang menutup sambungan dahulu (menghantar FIN pertama) melakukan penutupan aktif, dan bahagian lain (yang menerima FIN itu) melakukan penutupan pasif. Biasanya, satu bahagian melakukan penutupan aktif dan satu lagi melakukan penutupan pasif, walau bagaimanapun, dalam bahagian bab ini, kita akan melihat bahawa kedua-dua belah pihak boleh melakukan penutupan aktif.

Segmen nombor 4 dalam Rajah 18.3 menutup sambungan dan dihantar apabila pelanggan Telnet berhenti berfungsi. Ini berlaku apabila kita berhenti. Dalam kes ini, pelanggan TCP terpaksa menghantar FIN, menutup aliran data dari klien ke pelayan.

Apabila pelayan menerima FIN, ia menghantar kembali ACK dengan nombor urutan yang diterima tambah satu (segmen 5). FIN menggunakan satu nombor jujukan, sama seperti SYN. Pada ketika ini, pelayan TCP juga menghantar tanda akhir fail kepada aplikasi (untuk menutup pelayan). Pelayan kemudian menutup sambungannya, yang menyebabkan TCPnya menghantar FIN (segmen 6), yang pelanggan mesti akui (ACK) dengan menambah nombor urutan yang diterima (segmen 7).

Rajah 18.4 menunjukkan pertukaran tipikal segmen apabila menutup sambungan. Nombor urutan ditinggalkan. Dalam angka ini, FIN dihantar kerana aplikasi menutup sambungannya, manakala ACK untuk FIN ini dijana secara automatik oleh perisian TCP.

Sambungan biasanya diwujudkan oleh klien, iaitu, SYN pertama bergerak dari klien ke pelayan. Walau bagaimanapun, mana-mana pihak boleh menutup sambungan secara aktif (hantar FIN pertama). Selalunya, bagaimanapun, klienlah yang menentukan bila sambungan harus ditutup, kerana proses klien sebahagian besarnya dikawal oleh pengguna, yang memasukkan sesuatu seperti "berhenti" untuk menutup sambungan. Dalam Rajah 18.4, kita boleh membalikkan label di bahagian atas rajah, memanggil sebelah kiri pelayan, dan sebelah kanan oleh pelanggan. Walau bagaimanapun, walaupun dalam kes ini, semuanya akan berfungsi sama seperti yang ditunjukkan dalam rajah. (Contoh pertama dalam bahagian dalam Bab 14, sebagai contoh, menunjukkan cara pelayan masa menutup sambungan.)

Rajah 18.4 Pertukaran segmen biasa apabila menutup sambungan.

Keluaran tcpdump biasa

Memandangkan tugas menyusun sebilangan besar nombor jujukan adalah agak rumit, output program tcpdump mengandungi nombor jujukan lengkap untuk segmen SYN sahaja, dan semua nombor jujukan berikutnya ditunjukkan sebagai pengimbang relatif daripada nombor jujukan asal. (Untuk mendapatkan output yang ditunjukkan dalam Rajah 18.1, kami perlu menentukan pilihan -S.) Output tcpdump biasa yang sepadan dengan Rajah 18.1 ditunjukkan dalam Rajah 18.5.

1 0.0 svr4.1037 > bsdi.discard: S 1415531521:1415531521(0)
menang 4096
2 0.002402 (0.0024) bsdi.discard > svr4.1037: S 1823083521:1823083521(0)
ack 1415531522
menang 4096
3 0.007224 (0.0048) svr4.1037 > bsdi.buang: . ack 1 menang 4096
4 4.155441 (4.1482) svr4.1037 > bsdi.buang: F 1:1 (0) ack 1 menang 4096
5 4.156747 (0.0013) bsdi.discard > svr4.1037: . ack 2 menang 4096
6 4.158144 (0.0014) bsdi.discard > svr4.1037: F 1:1 (0) ack 2 menang 4096
7 4.180662 (0.0225) svr4.1037 > bsdi.buang: . ack 2 menang 4096

Rajah 18.5 Output arahan tcpdump biasa yang sepadan dengan penubuhan dan penamatan sambungan.

Melainkan kami mempunyai keperluan untuk menunjukkan nombor jujukan penuh, kami akan menggunakan bentuk output ini dalam semua contoh berikut.

Tamat masa apabila membuat sambungan

Terdapat beberapa sebab mengapa sambungan tidak dapat diwujudkan. Sebagai contoh, hos (pelayan) dimatikan. Untuk mensimulasikan situasi yang sama, kami melaksanakan arahan telnet, selepas memutuskan sambungan kabel Ethernet daripada pelayan. Rajah 18.6 menunjukkan output arahan tcpdump.

1 0.0 bsdi.1024 >
menang 4096
2 5.814797 (5.8148) bsdi.1024 > svr4.buang: S 291008001:291008001(0)
menang 4096
3 29.815436 (24.0006) bsdi.1024 > svr4.buang: S 291008001:291008001(0)
menang 4096

Rajah 18.6 Output arahan tcpdump untuk mewujudkan sambungan yang telah tamat masa.

Apa yang anda perlu beri perhatian dalam output ini ialah kekerapan klien TCP menghantar SYN dalam percubaan untuk mewujudkan sambungan. Segmen kedua dihantar 5.8 saat selepas yang pertama, dan yang ketiga dihantar 24 saat selepas yang kedua.

Perlu diingatkan bahawa contoh ini berjalan kira-kira 38 minit selepas pelanggan dibut semula. Oleh itu, nombor jujukan asal yang sepadan ialah 291008001 (kira-kira 38x60x6400x2). Pada permulaan bab, kami mengatakan bahawa sistem Berkeley biasa menetapkan nombor jujukan awal kepada 1 dan kemudian menambahnya sebanyak 64000 setiap setengah saat.

Ia juga harus diperhatikan bahawa ini adalah sambungan TCP pertama sejak sistem dibut semula, kerana nombor port klien ialah 1024.

Walau bagaimanapun, Rajah 18.6 tidak menunjukkan berapa lama klien TCP membuat penghantaran semula sebelum meninggalkan percubaannya. Untuk melihat nilai sementara ini, kita mesti melaksanakan arahan telnet seperti berikut:

bsdi % Tarikh ; telnet svr4 buang ; Tarikh
Kha 24 Sep 16:24:11 MST 1992
Mencuba 192.82.148.2...
telnet: Tidak dapat menyambung ke hos jauh: Sambungan tamat masa
Kha 24 Sep 16:25:27 MST 1992

Masa ialah 76 saat. Kebanyakan sistem Berkeley menetapkan had masa 75 saat, pada masa itu sambungan baharu mesti diwujudkan. Dalam bahagian Bab 21, kita akan melihat bahawa paket ketiga yang dihantar oleh pelanggan akan tamat masa pada kira-kira 16:25:29, iaitu, 48 saat selepas ia dihantar, tetapi pelanggan tidak akan berhenti mencuba selepas 75 saat .

Pertama kali keluar

Dalam Rajah 18.6, perhatikan bahawa tamat masa pertama, 5.8 saat, adalah hampir 6 saat tetapi bukan 6 saat, manakala tamat masa kedua hampir tepat 24 saat. Sepuluh lagi ujian serupa telah dilakukan, dan dalam setiap satu daripadanya nilai tamat masa pertama berjulat dari 5.59 saat hingga 5.93 saat. Tamat masa kedua, bagaimanapun, sentiasa 24.00 saat.

Ini kerana pelaksanaan TCP BSD memulakan pemasa setiap 500 milisaat. Pemasa 500 milisaat ini digunakan untuk pelbagai tamat masa TCP, yang kesemuanya akan diterangkan dalam bab berikut. Apabila kita memasukkan arahan telnet, pemasa awal 6 saat ditetapkan (12 detik jam), namun ia boleh tamat tempoh antara 5.5 dan 6 saat. Rajah 18.7 menunjukkan bagaimana ini berlaku.

Rajah 18.7 Pemasa TCP 500-ms.

Memandangkan pemasa ditetapkan kepada 12 detik, pengurangan pemasa pertama boleh berlaku antara 0 dan 500 milisaat selepas ia ditetapkan. Mulai saat ini, pemasa berkurangan kira-kira setiap 500 milisaat, tetapi tempoh masa pertama mungkin berbeza-beza. (Kami menggunakan perkataan "anggaran" kerana masa TCP menerima kawalan setiap 500 milisaat adalah anggaran, kerana gangguan lain mungkin berlalu dan dikendalikan oleh kernel.)

Apabila pemasa 6 saat ini tamat tempoh pada tanda berlabel 0 dalam Rajah 18.7, pemasa ditetapkan semula kepada 24 saat (48 detik). Pemasa seterusnya ini ialah 24 saat kerana ia telah ditetapkan pada titik masa apabila pemasa TCP 500 milisaat dipanggil oleh kernel dan bukan oleh pengguna.

Medan jenis perkhidmatan

Dalam Rajah 18.6 kita lihat ungkapan. Ini ialah medan jenis perkhidmatan (TOS - jenis perkhidmatan) dalam datagram IP (). Pelanggan Telnet dalam BSD/386 menetapkan medan ini untuk mencapai kependaman minimum.

Saiz segmen maksimum

Saiz segmen maksimum (MSS) ialah sekeping data terbesar yang akan dihantar oleh TCP ke hujung jauh. Apabila sambungan diwujudkan, setiap pihak boleh mengiklankan MSSnya. Nilai yang kami lihat ialah 1024. Datagram IP yang terhasil biasanya 40 bait lebih besar: 20 bait diperuntukkan untuk pengepala TCP dan 20 bait untuk pengepala IP.

Sesetengah penerbitan mengatakan bahawa pilihan ini dipasang "dengan persetujuan". Pada hakikatnya, perjanjian itu tidak digunakan dalam kes ini. Apabila sambungan diwujudkan, setiap pihak mengiklankan MSS yang ingin diterima. (Pilihan MSS hanya boleh digunakan dalam segmen SYN.) Jika satu pihak tidak menerima pilihan MSS dari sisi lain, saiz lalai 536 bait digunakan. (Dalam kes ini, dengan pengepala IP 20-bait dan pengepala TCP 20-bait, saiz datagram IP ialah 576 bait.)

Secara umum, lebih banyak MSS lebih baik, selagi pemecahan tidak berlaku. (Ini tidak selalu benar. Rujuk dan untuk mengesahkan ini.) Saiz besar segmen membolehkan lebih banyak data dihantar dalam setiap segmen, yang mengurangkan kos relatif pengepala IP dan TCP. Apabila TCP menghantar segmen SYN, atau bila aplikasi tempatan ingin mewujudkan sambungan, atau apabila permintaan sambungan diterima daripada hos jauh, nilai MSS boleh ditetapkan sama dengan MTU antara muka keluar tolak saiz pengepala TCP dan IP tetap. Untuk Ethernet, MSS boleh mencapai sehingga 1460 bait. Apabila menggunakan enkapsulasi IEEE 802.3 (Bab 2, Bahagian), MSS boleh mencapai sehingga 1452 bait.

Nilai 1024 yang kita lihat dalam bab ini sepadan dengan sambungan yang melibatkan BSD/386 dan SVR4, kerana kebanyakan pelaksanaan BSD memerlukan MSS menjadi gandaan 512. Sistem lain seperti SunOS 4.1.3, Solaris 2.2 dan AIX 3.2 . 2, mengisytiharkan MSS 1460 apabila kedua-dua belah berada pada Ethernet yang sama. Pengiraan yang diberikan dalam [Mogul 1993] menunjukkan bahawa MSS 1460 memberikan prestasi Ethernet yang lebih baik daripada MSS 1024.

Jika alamat IP destinasi ialah "bukan tempatan", MSS biasanya ditetapkan kepada lalai - 536. Sama ada destinasi akhir tempatan atau bukan tempatan boleh ditentukan seperti berikut. Destinasi yang alamat IPnya mempunyai ID rangkaian yang sama dan subnet mask yang sama seperti pengirim adalah setempat; destinasi yang alamat IPnya berbeza sama sekali daripada ID rangkaian adalah bukan tempatan; destinasi dengan ID rangkaian yang sama, tetapi dengan topeng subnet yang berbeza, boleh sama ada tempatan atau bukan tempatan. Kebanyakan pelaksanaan menyediakan pilihan konfigurasi ( dan ) yang membolehkan pentadbir sistem menentukan subnet yang tempatan dan yang bukan tempatan. Menetapkan pilihan ini menentukan MSS maksimum yang diiklankan (yang boleh sebesar MTU antara muka keluar), jika tidak, nilai lalai 536 digunakan.

MSS membenarkan hos menetapkan saiz datagram yang akan dihantar oleh pihak jauh. Jika anda mengambil kira hakikat bahawa hos juga mengehadkan saiz datagram yang dihantar, ini mengelakkan pemecahan apabila hos disambungkan ke rangkaian dengan MTU yang lebih kecil.

Bayangkan slip hos kami, yang mempunyai saluran SLIP dengan MTU 296, disambungkan ke penghala bsdi. Rajah 18.8 menunjukkan sistem ini dan matahari perumah.

Rajah 18.8 Sambungan TCP dari matahari ke gelinciran dan nilai MSS.

Kami mewujudkan sambungan TCP dari matahari hingga tergelincir dan mengimbas segmen menggunakan tcpdump. Rajah 18.9 menunjukkan hanya penubuhan sambungan (pengisytiharan saiz tetingkap dialih keluar).

1 0.0 matahari.1093 > slip.buang: S 517312000:517312000(0)

2 0.10 (0.00) slip.buang > matahari.1093: S 509556225:509556225(0)
ack 517312001
3 0.10 (0.00) matahari.1093 > slip.buang: . ack 1

Rajah 18.9 Keluaran Tcpdump untuk mewujudkan sambungan dari matahari ke gelinciran.

Perkara penting yang perlu diperhatikan di sini ialah matahari tidak boleh menghantar segmen dengan ketulan data yang lebih besar daripada 256 bait, kerana ia menerima MSS sebanyak 256 (baris 2). Selain itu, kerana slip mengetahui bahawa MTU antara muka keluar ialah 296, walaupun matahari mengiklankan MSS sebanyak 1460, ia tidak boleh menghantar lebih daripada 256 bait data untuk mengelakkan pemecahan. Walau bagaimanapun, sistem mungkin menghantar kurang data daripada MSS yang diiklankan oleh pihak jauh.

Pemecahan hanya boleh dielakkan dengan cara ini jika hos disambungkan terus ke rangkaian dengan MTU kurang daripada 576. Jika kedua-dua hos disambungkan ke Ethernet dan kedua-duanya mengiklankan MSS sebanyak 536, tetapi rangkaian perantaraan mempunyai MTU sebanyak 296, pemecahan akan berlaku. Satu-satunya cara untuk mengelakkan ini adalah dengan menggunakan mekanisme penemuan MTU pengangkutan (Bab 24, bahagian).

Separuh TCP peribadi

TCP menyediakan keupayaan untuk satu pihak kepada sambungan untuk menghentikan penghantaran data tetapi masih menerima data daripada pihak lain. Ini dipanggil TCP separuh tertutup. Seperti yang kami nyatakan sebelum ini, tidak banyak aplikasi boleh memanfaatkan ciri ini.

Untuk menggunakan ciri antara muka pengaturcaraan ini, anda perlu membenarkan aplikasi untuk berkata, "Saya telah selesai memindahkan data, jadi saya menghantar penunjuk akhir fail (FIN) ke hujung jauh, tetapi saya masih mahu menerima data dari hujung jauh sebelum itu." sehingga ia menghantar saya tanda akhir fail (FIN)."

API soket menyokong mod separa tertutup jika aplikasi memanggil penutupan dengan hujah kedua 1 dan bukannya memanggil tutup. Kebanyakan aplikasi, bagaimanapun, menutup sambungan dalam kedua-dua arah dengan memanggil dekat.

Rajah 18.10 menunjukkan senario tipikal untuk TCP separa tertutup. Kami telah menunjukkan pelanggan di sebelah kiri, dia memulakan mod separa tertutup, bagaimanapun, kedua-dua pihak boleh melakukan ini. Dua segmen pertama adalah sama: FIN daripada pemula, diikuti oleh ACK dan FIN daripada penerima. Walau bagaimanapun, senario akan berbeza daripada yang ditunjukkan dalam Rajah 18.4 kerana pihak yang menerima pesanan separuh tutup mungkin masih menghantar data. Kami telah menunjukkan hanya satu segmen data diikuti dengan ACK, tetapi dalam kes ini sebarang bilangan segmen data boleh dihantar. (Kami akan merangkumi pertukaran segmen data dan pengakuan dengan lebih terperinci dalam .) Apabila penghujung yang menerima pesanan separuh tutup telah membuat pemindahan data, ia menutup bahagian sambungannya, menyebabkan FIN dihantar, dengan bendera akhir fail dihantar ke aplikasi yang memulakan mod "separuh tertutup". Apabila FIN kedua disahkan, sambungan dianggap tertutup sepenuhnya.

Rajah 18.10 TCP dalam mod separuh tertutup.

Untuk apa mod separuh tertutup boleh digunakan? Satu contoh boleh jadi Perintah Unix rsh(1), yang melaksanakan arahan pada sistem lain. Pasukan

matahari% rsh bsdi sort< datafile

akan menjalankan perintah isihan pada hos bsdi, dengan input standard perintah rsh dibaca daripada fail bernama datafile. Perintah rsh mencipta sambungan TCP antara dirinya dan program yang akan dilaksanakan pada hos jauh. rsh kemudian berfungsi dengan mudah: arahan menyalin input standard (fail data) ke dalam sambungan dan menyalin dari sambungan ke output standard (terminal kami). Rajah 18.11 menunjukkan bagaimana ini berlaku. (Kami ingat bahawa sambungan TCP adalah dupleks penuh.)

Rajah 18.11 Perintah: rsh bsdi sort< datafile.

Pada bsdi hos jauh, pelayan rshd menjalankan program isihan supaya input standard dan output standardnya diarahkan ke sambungan TCP. Bab 14 memberikan penerangan terperinci tentang struktur proses Unix yang terlibat di sini, tetapi kami berminat dengan cara sambungan TCP dan mod separuh tertutup TCP digunakan.

Program isihan tidak boleh mula menjana output sehingga semua inputnya dibaca. Semua data mentah yang datang melalui sambungan daripada klien rsh ke pelayan isihan dihantar ke fail yang hendak diisih. Apabila tanda akhir fail dalam input (fail data) dicapai, klien rsh melakukan penutupan separuh sambungan TCP. Pelayan isihan kemudian mengambil tanda akhir fail daripadanya input standard(sambungan TCP), mengisih fail dan menulis hasilnya kepada output standardnya (sambungan TCP). Pelanggan rsh terus membaca sambungan TCP pada penghujungnya, menyalin fail yang diisih ke output standardnya.

Tanpa menggunakan mod separuh tertutup, beberapa teknik tambahan diperlukan yang membolehkan klien memberitahu pelayan bahawa ia telah selesai menghantar data, tetapi klien masih dibenarkan menerima data daripada pelayan. Sebagai alternatif, dua sambungan mesti digunakan, tetapi mod separa tertutup lebih disukai.

Rajah Keadaan Penghantaran TCP

Kami telah menerangkan beberapa peraturan untuk mewujudkan dan memutuskan sambungan TCP. Peraturan ini disusun menjadi gambar rajah keadaan penghantaran, yang ditunjukkan dalam Rajah 18.12.

Perlu diingatkan bahawa rajah ini adalah rajah keadaan piawai. Kami telah menandakan pemindahan pelanggan biasa dengan kukuh anak panah tebal, dan pemindahan pelayan biasa dengan anak panah tebal bertitik.

Kedua-dua pemindahan yang membawa kepada keadaan ESTABLISHED sepadan dengan pembukaan sambungan, dan dua pemindahan yang membawa daripada keadaan ESTABLISHED sepadan dengan penamatan sambungan. Keadaan ESTABLISHED berlaku pada masa apabila ia menjadi mungkin untuk memindahkan data antara dua pihak dalam kedua-dua arah. Bab berikut akan menerangkan apa yang berlaku di negeri ini.

Kami telah menggabungkan empat kotak di bahagian bawah sebelah kiri gambar rajah di dalam kotak bertitik dan melabelkannya "tutup aktif". Dua petak yang lain (CLOSE_WAIT dan LAST_ACK) dicantumkan dengan bingkai bertitik dan dilabel "tutup pasif".

Nama 11 negeri (TUTUP, DENGAR, SYN_SENT dan seterusnya) dalam rajah ini dipilih untuk sepadan dengan keluaran keadaan oleh perintah netstat. Nama netstat pula, hampir sama dengan nama yang diterangkan dalam RFC 793. Keadaan TERTUTUP sebenarnya bukan keadaan, tetapi ia adalah titik permulaan dan penamat untuk rajah.

Menukar keadaan daripada LISTEN kepada SYN_SENT secara teorinya mungkin, tetapi tidak disokong dalam pelaksanaan Berkeley.

Dan perubahan keadaan daripada SYN_RCVD kembali kepada LISTEN hanya boleh dilakukan jika keadaan SYN_RCVD telah dimasukkan daripada keadaan LISTEN (ini adalah senario biasa), dan bukan daripada keadaan SYN_SENT (pembukaan serentak). Ini bermakna jika kami melakukan buka pasif (memasuki keadaan LISTEN), menerima SYN, menghantar SYN dengan ACK (masuk keadaan RECEIVED_SYN - SYN_RCVD) dan kemudian menerima tetapan semula dan bukannya ACK, titik akhir kembali ke LISTEN nyatakan dan tunggu permintaan sambungan lain tiba.

Rajah 18.12 Rajah perubahan keadaan TCP.

Rajah 18.13 menunjukkan penubuhan dan penamatan sambungan TCP biasa. Juga diterangkan secara terperinci negeri yang berbeza, yang dilalui oleh klien dan pelayan.

Rajah 18.13 TCP menyatakan sepadan dengan pembukaan dan penutup sambungan biasa.

Dalam Rajah 18.13, kami mengandaikan bahawa klien di sebelah kiri melakukan buka aktif, dan pelayan di sebelah kanan melakukan buka pasif. Kami juga menunjukkan bahawa pelanggan melakukan penutupan aktif (seperti yang kami nyatakan sebelum ini, mana-mana pihak boleh melakukan penutupan aktif).

Anda harus mengesan perubahan keadaan dalam Rajah 18.13 menggunakan datagram perubahan keadaan yang ditunjukkan dalam Rajah 18.12 untuk memahami mengapa perubahan keadaan tertentu berlaku.

Keadaan siap sedia 2MSL

Keadaan TIME_WAIT juga kadangkala dipanggil keadaan menunggu 2MSL. Setiap pelaksanaan memilih nilai untuk hayat segmen maksimum (MSL - hayat segmen maksimum). ini masa maksimum berapa lama segmen boleh wujud pada rangkaian sebelum ia dibuang. Kami tahu bahawa masa ini terhad kerana segmen TCP dihantar melalui datagram IP, dan setiap datagram IP mempunyai medan TTL yang mengehadkan hayatnya.

RFC 793 [Postel 1981c] menyatakan bahawa MSL hendaklah 2 minit. DALAM pelaksanaan yang berbeza nilai ini ialah 30 saat, 1 minit atau 2 minit.

Dikatakan bahawa jangka hayat datagram IP dihadkan oleh bilangan pemindahan, bukan oleh pemasa.

Apabila menggunakan MSL, peraturan berikut dikenakan: apabila TCP melakukan penutupan aktif dan menghantar segmen terakhir yang mengandungi pengakuan (ACK), sambungan mesti kekal dalam keadaan TIME_WAIT untuk tempoh yang sama dengan dua MSL. Ini membolehkan TCP menghantar semula ACK terakhir sekiranya ACK pertama hilang (dalam kes ini bahagian jauh akan tamat masa dan menghantar semula FIN terakhirnya).

Satu lagi tujuan menunggu 2MSL ialah semasa sambungan TCP menunggu 2MSL, pasangan soket yang diperuntukkan untuk sambungan tersebut (alamat IP pelanggan, nombor port klien, alamat IP pelayan dan nombor port pelayan) tidak boleh digunakan semula. Sambungan ini hanya boleh digunakan semula apabila tamat masa 2MSL tamat.

Malangnya, kebanyakan pelaksanaan (Berkeley adalah salah satu daripadanya) tertakluk kepada keperluan yang lebih ketat. Secara lalai, nombor port tempatan tidak boleh digunakan semula selagi nombor port itu ialah nombor port tempatan pasangan soket yang berada dalam keadaan tunggu 2MSL. Di bawah ini kita akan melihat contoh keperluan umum.

Sesetengah pelaksanaan dan API menyediakan alatan yang membolehkan anda mengatasi pengehadan ini. Menggunakan API soket, pilihan soket SO_REUSEADDR boleh ditentukan. Ia membolehkan pemanggil untuk memberikan dirinya nombor pelabuhan tempatan yang berada dalam keadaan 2MSL, namun kita akan melihat bahawa peraturan TCP tidak membenarkan nombor port ini digunakan pada sambungan yang berada dalam keadaan menunggu 2MSL.

Setiap segmen tertangguh yang tiba pada sambungan yang berada dalam keadaan menunggu 2MSL akan dibuang. Memandangkan sambungan ditakrifkan oleh sepasang soket dalam keadaan 2MSL, sambungan ini tidak boleh digunakan semula sehingga kami boleh mewujudkan sambungan baharu. Ini dilakukan untuk memastikan paket lewat tidak diterima sebagai sebahagian daripada sambungan baharu. (Sambungan ditakrifkan oleh sepasang soket. Sambungan baharu dipanggil pemulihan atau pemulihan sambungan itu.)

Seperti yang telah kami tunjukkan dalam Rajah 18.13, pelanggan biasanya melakukan penutupan aktif dan memasuki mod TIME_WAIT. Pelayan biasanya melakukan penutupan pasif dan tidak melalui mod TIME_WAIT. Kami boleh menyimpulkan bahawa jika kami menutup klien dan memulakan semula dengan serta-merta, pelanggan baharu ini tidak akan dapat menggunakan nombor port tempatan yang sama. Ini bukan masalah kerana pelanggan biasanya menggunakan port yang diperuntukkan secara dinamik dan tidak peduli port yang diperuntukkan secara dinamik yang sedang digunakan.

Walau bagaimanapun, dari sudut pandangan pelayan semuanya berbeza, kerana pelayan digunakan terlebih dahulu pelabuhan terkenal. Jika kami menutup pelayan yang mempunyai sambungan yang telah ditetapkan dan cuba memulakan semulanya dengan segera, pelayan tidak boleh menggunakan nombor port yang diketahui sebelum ini sebagai titik akhir sambungan, kerana nombor port itu adalah sebahagian daripada sambungan yang berada dalam keadaan menunggu 2MSL . Oleh itu, ia mungkin mengambil masa 1 hingga 4 minit sebelum pelayan dimulakan semula.

Anda boleh melihat senario yang sama menggunakan program stokin. Kami memulakan pelayan, menyambungkan klien kepadanya, dan kemudian mematikan pelayan:

matahari% stokin -v -s 6666
(mulakan klien pada bsdi, yang akan menyambung ke port ini)
sambungan pada 140.252.13.33.6666 daripada140.252.13.35.1081
^? masukkan aksara gangguan untuk menutup pelayan
matahari% stokin -s 6666 dan cuba untuk segera memulakan semula pelayan pada port yang sama
tidak boleh mengikat alamat setempat: Alamat sudah digunakan
matahari% netstat mari cuba semak status sambungan
Sambungan Internet aktif
Proto Recv-Q Send-Q Alamat Tempatan Alamat Asing (negeri)
tcp 0 0 sun.6666 bsdi.1081 TIME_WAIT
banyak baris dipadamkan

Apabila kami cuba memulakan semula pelayan, program melemparkan mesej ralat yang menunjukkan bahawa ia tidak dapat menangkap nombor portnya yang telah diketahui kerana ia sudah digunakan (dalam keadaan menunggu 2MSL).

Kami kemudiannya segera menjalankan netstat untuk melihat keadaan sambungan dan mengesahkan bahawa ia sememangnya dalam keadaan TIME_WAIT.

Jika kita terus mencuba untuk memulakan semula pelayan dan melihat masa apabila ia berjaya, kita boleh mengira nilai 2MSL. Untuk SunOS 4.1.3, SVR4, BSD/386 dan AIX 3.2.2, memulakan semula pelayan akan mengambil masa 1 minit, yang bermaksud MSL ialah 30 saat. Dalam Solaris 2.2, permulaan semula pelayan ini mengambil masa 4 minit, yang bermaksud MSL ialah 2 minit.

Kita boleh melihat ralat yang sama yang dijana oleh klien jika klien cuba merampas port yang merupakan sebahagian daripada sambungan yang berada dalam mod melahu 2MSL (biasanya klien tidak melakukan ini):

matahari% sock -v bsdi echo kami memulakan klien yang menyambung ke pelayan gema
disambungkan pada 140.252.13.33.1162 hingga 140.252.13.35.7
apa khabar di sana cetak baris ini
hello, ia bergema dari pelayan
^D masukkan aksara akhir fail untuk mematikan klien
matahari% stokin -b1162 bsdi echo
tidak boleh mengikat alamat setempat: Alamat sudah digunakan

Apabila klien mula-mula dilancarkan, pilihan -v telah ditentukan, yang membolehkan anda melihat nombor port tempatan yang sedang digunakan (1162). Kali kedua klien dijalankan, pilihan -b telah ditentukan, yang memberitahu klien untuk menetapkan sendiri nombor port tempatan 1162. Seperti yang kami jangka, pelanggan tidak boleh melakukan ini, kerana nombor port ini adalah sebahagian daripada sambungan yang dalam keadaan 2MSL.

Adalah perlu untuk menyebut di sini satu ciri keadaan menunggu 2MSL, yang akan kita kembalikan apabila kita bercakap tentang Protokol Pemindahan Fail (FTP - Pemindahan fail protokol). Seperti yang dinyatakan sebelum ini, sepasang soket (terdiri daripada alamat IP tempatan, port tempatan, alamat IP jauh dan port jauh) kekal dalam keadaan menunggu 2MSL. Walau bagaimanapun, walaupun banyak pelaksanaan membenarkan proses untuk menggunakan semula nombor port yang merupakan sebahagian daripada sambungan yang berada dalam mod 2MSL (biasanya menggunakan pilihan SO_REUSEADDR), TCP mungkin tidak membenarkan sambungan baharu dibuat pada pasangan soket yang sama. Ini boleh dibuktikan menggunakan eksperimen berikut:

matahari% stokin -v -s 6666 permulaan pelayan mendengar pada port 6666
(kami melancarkan klien pada bsdi, yang bersambung ke port ini)
sambungan pada 140.252.13.33.6666 daripada 140.252.13.35.1098
^? masukkan aksara gangguan untuk menutup pelayan
matahari% sock-b6666 bsdi 1098 kami memulakan pelanggan dengan port tempatan 6666
tidak boleh mengikat alamat setempat: Alamat sudah digunakan
matahari% stokin -A -b6666 bsdi 1098 cuba lagi, kali ini dengan pilihan -A
ralat terbuka aktif: Alamat sudah digunakan

Kali pertama kami menjalankan program sock kami sebagai pelayan pada port 6666 dan menyambungkan klien kepadanya daripada hos bsdi. Nombor port yang diberikan secara dinamik kepada pelanggan ialah 1098. Kami menutup pelayan, jadi ia melakukan penutupan aktif. Dalam kes ini, 4 parameter - 140.252.13.33 (alamat IP tempatan), 6666 (nombor port tempatan), 140.252.13.35 (alamat IP jauh) dan 1098 (nombor port jauh) pada pelayan jatuh ke dalam keadaan 2MSL.

Kali kedua kami menjalankan program ini sebagai pelanggan, dengan menyatakan nombor port tempatan 6666, ia cuba menyambung ke hos bsdi pada port 1098. Apabila kami cuba menggunakan semula port tempatan 6666, ralat telah dijana kerana port ini dalam keadaan 2MSL .

Untuk mengelakkan ralat ini, kami menjalankan program sekali lagi dengan pilihan -A, yang membolehkan pilihan SO_REUSEADDR. Ini membenarkan atur cara menetapkan sendiri nombor port 6666, tetapi ia menerima ralat apabila program cuba melakukan buka aktif. Walaupun program boleh menetapkan sendiri nombor port 6666, ia tidak akan dapat membuat sambungan ke port 1098 pada hos bsdi kerana pasangan soket yang mentakrifkan sambungan ini berada dalam keadaan menunggu 2MSL.

Bagaimana jika kita cuba mewujudkan sambungan daripada hos lain? Mula-mula, kita mesti memulakan semula pelayan di matahari dengan bendera -A, kerana port yang diperlukannya (6666) adalah sebahagian daripada sambungan yang berada dalam keadaan menunggu 2MSL:

matahari% stokin -A -s 6666 mulakan pelayan mendengar pada port 6666

Kemudian, sebelum keadaan menunggu 2MSL berakhir pada matahari, kami memulakan pelanggan di bsdi:

bsdi % stokin -b1098 matahari 6666
disambungkan pada 140.252.13.35.1098 hingga 140.252.13.33.6666

Malangnya, ia berfungsi! Ini adalah kelemahan spesifikasi TCP, tetapi disokong oleh kebanyakan pelaksanaan Berkeley. Pelaksanaan ini menerima ketibaan permintaan sambungan baharu untuk sambungan yang berada dalam keadaan TIME_WAIT jika nombor jujukan baharu lebih besar daripada nombor jujukan terakhir yang digunakan dalam sambungan sebelumnya. Dalam kes ini, ISN untuk sambungan baharu ditetapkan kepada nombor urutan terakhir untuk sambungan sebelumnya ditambah 128000. Lampiran kepada RFC 1185 menunjukkan kemungkinan kelemahan teknologi ini.

Ciri pelaksanaan ini membolehkan klien dan pelayan menggunakan semula nombor port yang sama untuk berjaya mewujudkan semula sambungan yang sama, dengan syarat, bagaimanapun, pelayan tidak menutupnya secara aktif. Kita akan melihat satu lagi contoh keadaan menunggu 2MSL pada , apabila kita membincangkan FTP. Rujuk juga bab ini.

Konsep masa tenang

Keadaan menunggu 2MSL memberikan perlindungan terhadap paket lewat kepunyaan sambungan terdahulu, supaya ia tidak akan ditafsirkan sebagai sebahagian daripada sambungan baharu yang menggunakan alamat IP tempatan dan jauh dan nombor port yang sama. Walau bagaimanapun, ini hanya berfungsi jika hos dengan sambungan dalam keadaan 2MSL tidak gagal.

Bagaimana jika hos dengan port dalam keadaan 2MSL ranap, but semula semasa MSL, dan segera mewujudkan sambungan baharu menggunakan alamat IP tempatan dan jauh yang sama serta nombor port yang sepadan dengan port tempatan yang berada dalam keadaan 2MSL sebelum kegagalan? Dalam kes ini, segmen lewat daripada sambungan yang wujud sebelum kegagalan mungkin disalahtafsirkan sebagai milik sambungan baharu yang dibuat selepas but semula. Ini mungkin berlaku tanpa mengira nombor jujukan awal yang dipilih selepas but semula.

Untuk melindungi daripada senario yang tidak diingini sedemikian, RFC 793 menentukan bahawa TCP tidak seharusnya membuat sambungan baharu sehingga MSL tamat tempoh selepas masa but. Ini dipanggil masa tenang.

Dalam sesetengah pelaksanaan, hos menunggu lebih lama daripada masa MSL selepas but semula.

Nyatakan WAIT_AND_CONFIRMATION_FIN (FIN_WAIT_2)

Dalam keadaan FIN_WAIT_2 kami menghantar FIN kami dan pihak jauh mengakuinya. Jika kami tidak berada dalam keadaan sambungan separuh tertutup, kami menjangkakan aplikasi di hujung jauh akan mengenali bahawa hujung fail telah diterima dan menutup bahagian sambungannya dan menghantar FIN kepada kami. Hanya apabila proses di hujung jauh melakukan penutupan ini, penghujung kami akan bertukar daripada mod FIN_WAIT_2 kepada mod TIME_WAIT.

Ini bermakna bahagian sambungan kami mungkin kekal dalam mod ini selama-lamanya. Bahagian jauh masih dalam keadaan CLOSE_WAIT dan mungkin kekal dalam keadaan itu selama-lamanya sehingga aplikasi memutuskan untuk ditutup.

Kebanyakan pelaksanaan Berkeley menghalang jenis menunggu selama-lamanya dalam keadaan FIN_WAIT_2 seperti berikut. Jika aplikasi yang melakukan penutupan aktif melakukan penutupan penuh daripada penutupan separuh, menunjukkan bahawa ia sedang menunggu untuk menerima data, maka pemasa ditetapkan. Jika sambungan melahu selama 10 minit ditambah 75 saat, TCP meletakkan sambungan dalam mod TUTUP. Komen menyatakan bahawa ciri sedemikian tidak konsisten dengan spesifikasi protokol.

Tetapkan semula segmen

Kami menyebut bahawa terdapat sedikit dalam pengepala TCP yang dipanggil RST, yang bermaksud set semula. Secara umum, isyarat set semula dihantar oleh TCP jika segmen yang tiba bukan milik sambungan yang ditentukan. (Kami menggunakan istilah "sambungan rujukan", yang bermaksud sambungan yang dikenal pasti oleh alamat IP destinasi dan nombor port destinasi, dan alamat IP sumber dan nombor port sumber. Dalam RFC 793, ini dipanggil "soket".)

Permintaan sambungan pada port yang tidak wujud

Kes yang paling biasa di mana tetapan semula dijana ialah apabila permintaan sambungan tiba dan tiada proses mendengar pada port destinasi. Dalam kes UDP, seperti yang kita lihat dalam bahagian Bab 6, jika datagram tiba pada port destinasi yang tidak digunakan, ralat tidak boleh dicapai port ICMP dijana. TCP menggunakan tetapan semula.

Kami akan memberikan contoh mudah dengan menggunakan Telnet pelanggan, menyatakan nombor port yang tidak digunakan di destinasi:

bsdi % telnet svr4 20000 port 20000 tidak digunakan
Mencuba 140.252.13.34...
telnet: Tidak dapat menyambung ke hos jauh: Sambungan ditolak

Mesej ralat dilaporkan kepada pelanggan Telnet serta-merta. Rajah 18.14 menunjukkan pertukaran paket yang sepadan dengan arahan ini.

1 0.0 bsdi.1087 > svr4.20000: S 297416193:297416193(0)
menang 4096
2 0.003771 (0.0038) svr4.20000 > bsdi.1087: R 0:0 (0) ack 297416194 menang 0

Rajah 18.14 Menjana tetapan semula apabila cuba membuka sambungan ke port yang tidak wujud.

Nilai yang perlu kita lihat dengan lebih terperinci dalam angka ini ialah medan nombor jujukan dan medan nombor pengakuan dalam tetapan semula. Oleh kerana bit pengakuan (ACK) tidak ditetapkan pada segmen yang tiba, nombor urutan set semula ditetapkan kepada 0 dan nombor pengakuan ditetapkan kepada nombor urutan permulaan (ISN) masuk ditambah bilangan bait data dalam segmen. Walaupun tiada data sebenar hadir dalam segmen yang tiba, bit SYN secara logiknya menduduki 1 bait dalam ruang nombor jujukan; Oleh itu, dalam contoh ini, nombor pengakuan dalam set semula ditetapkan kepada ISN ditambah panjang data (0) ditambah satu bit SYN.

Pemutusan sambungan

Dalam bahagian bab ini kita melihatnya kaedah biasa Kaedah yang digunakan untuk menamatkan sambungan adalah untuk salah satu pihak menghantar FIN. Ini kadangkala dipanggil keluaran teratur kerana FIN dihantar selepas semua data yang beratur sebelum ini dihantar, dan biasanya tiada kehilangan data berlaku. Walau bagaimanapun, adalah mungkin untuk menamatkan sambungan dengan menghantar tetapan semula dan bukannya FIN. Ini kadangkala dipanggil pelepasan abortif.

Penamatan sambungan jenis ini memberikan dua pilihan kepada aplikasi: (1) sebarang data dalam baris gilir hilang dan tetapan semula dihantar serta-merta, dan (2) pihak yang menerima RST boleh mengatakan bahawa pihak jauh telah menutup sambungan, bukannya menutupnya seperti biasa. Antara muka pengaturcaraan aplikasi (API) yang digunakan oleh aplikasi mesti menyediakan cara untuk menjana tetapan semula sedemikian dan bukannya penutupan biasa.

Kita boleh melihat apa yang berlaku apabila rehat seperti ini berlaku menggunakan program stokin kami. API soket menyediakan keupayaan ini menggunakan pilihan berlama-lama pada soket tertutup (SO_LINGER). Kami menetapkan pilihan -L dengan masa tunda 0. Ini bermakna bukannya FIN biasa, tetapan semula akan dihantar untuk menutup sambungan. Kami akan menyambung ke versi pelayan program sock pada svr4:

bsdi % stokin -L0 svr4 8888 ini adalah pelanggan; pelayan ditunjukkan seterusnya
Hai dunia masukkan satu baris yang akan dihantar ke hujung terpencil
^D masukkan aksara akhir fail untuk mematikan klien

Rajah 18.15 menunjukkan output arahan tcpdump untuk contoh ini. (Kami telah mengalih keluar semua pengisytiharan tetingkap dalam angka ini kerana ia tidak menjejaskan alasan kami.)

1 0.0 bsdi.1099 > svr4.8888: S 671112193:671112193(0)

2 0.004975 (0.0050) svr4.8888 > bsdi.1099: S 3224959489:3224959489(0)
ack 671112194
3 0.006656 (0.0017) bsdi.1099 > svr4.8888: . ack 1
4 4.833073 (4.8264) bsdi.1099 > svr4.8888: P 1:14 (13) ack 1
5 5.026224 (0.1932) svr4.8888 > bsdi.1099: . ack 14
6 9.527634 (4.5014) bsdi.1099 > svr4.8888: R 14:14 (0) ack 1

Rajah 18.15 Menamatkan sambungan menggunakan tetapan semula (RST) dan bukannya FIN.

Baris 1-3 menunjukkan persediaan sambungan biasa. Baris 4 menghantar rentetan data yang kami cetak (12 aksara ditambah baris baharu Unix), dan baris 5 menerima pengakuan bahawa data telah diterima.

Baris 6 sepadan dengan input akhir fail (Kawalan-D) yang kami gunakan untuk menutup klien. Memandangkan kami menetapkan rehat dan bukannya tutup biasa (pilihan baris arahan -L0), TCP pada bsdi akan menghantar RST dan bukannya FIN biasa. Segmen RST mengandungi nombor urutan dan nombor pengesahan. Juga ambil perhatian bahawa segmen RST tidak menjangkakan respons daripada hujung jauh - ia tidak mengandungi pengakuan sama sekali. Penerima set semula menamatkan sambungan dan memaklumkan aplikasi bahawa sambungan telah ditamatkan.

Kami akan menerima ralat berikut daripada pelayan dengan pertukaran sedemikian:

svr4% stokin -s 8888 jalankan sebagai pelayan, dengarkan port 8888
hello, dunia inilah yang dihantar oleh pelanggan
ralat baca: Tetapan semula sambungan oleh rakan sebaya

Pelayan ini membaca dari rangkaian dan menyalin semua yang diterima ke output standard. Biasanya ia keluar selepas menerima tanda akhir fail daripada TCPnya, namun di sini kita melihat bahawa ia menerima ralat apabila RST tiba. Ralat adalah tepat seperti yang kami jangkakan: sambungan telah ditutup oleh salah seorang peserta sambungan.

Menentukan Sambungan Separuh Terbuka

Sambungan TCP dianggap separuh terbuka jika satu pihak telah menutup atau menamatkan sambungan tanpa memberitahu pihak lain. Ini boleh berlaku pada bila-bila masa jika salah satu daripada dua hos gagal. Memandangkan tiada percubaan untuk menghantar data melalui sambungan separuh terbuka untuk beberapa waktu, salah satu pihak akan berfungsi sehingga ia menentukan bahawa pihak jauh telah gagal.

Sebab lain mengapa sambungan separuh terbuka mungkin berlaku ialah hos pelanggan telah dimatikan dan bukannya menutup aplikasi klien dan kemudian mematikan komputer. Ini berlaku apabila, sebagai contoh, pelanggan Telnet dilancarkan pada PC, dan pengguna mematikan komputer pada penghujung hari bekerja. Jika tiada data dipindahkan semasa PC dimatikan, pelayan tidak akan tahu bahawa klien telah hilang. Apabila pengguna datang keesokan paginya, menghidupkan PCnya dan memulakan klien Telnet baharu, pelayan baharu bermula pada hos pelayan. Oleh sebab itu, banyak sambungan TCP terbuka mungkin muncul pada hos pelayan. (Dalam kita akan melihat cara di mana satu hujung sambungan TCP boleh mengesan bahawa yang lain telah hilang. Ini dilakukan menggunakan pilihan "keepalive" TCP.)

Kami boleh membuat sambungan separuh terbuka dengan mudah. Kami melancarkan klien Telnet pada bsdi dan menyambung ke pelayan buang pada svr4. Kami memasuki satu baris dan menggunakan tcpdump untuk melihat bagaimana ia berjalan, dan kemudian putuskan sambungan kabel Ethernet daripada hos pelayan dan mulakannya semula. Dengan melakukan ini, kami mensimulasikan kegagalan hos pelayan. (Kami memutuskan sambungan kabel Ethernet sebelum but semula pelayan untuk menghalangnya daripada menghantar FIN pada sambungan terbuka, yang dilakukan oleh sesetengah modul TCP apabila dimatikan.) Selepas pelayan but semula, kami menyambung semula kabel dan cuba menghantar talian lain daripada klien ke pelayan. Oleh kerana pelayan telah dibut semula dan telah kehilangan semua data sambungan yang wujud sebelum but semula, ia tidak mengetahui apa-apa tentang sambungan dan tidak mengetahui sambungan mana yang dimiliki oleh segmen yang tiba. Dalam kes ini, pihak TCP yang menerima bertindak balas dengan tetapan semula.

bsdi % telnet svr4 buang pelancaran pelanggan
Mencuba 140.252.13.34...
Disambungkan ke svr4.
Watak melarikan diri ialah "^]".
hai talian ini dihantar seperti biasa
pada ketika ini kami but semula hos pelayan
baris lain penetapan semula telah dilakukan di lokasi ini
Sambungan ditutup oleh hos asing.

Rajah 18.16 menunjukkan output tcpdump untuk contoh ini. (Kami telah mengalih keluar pengisytiharan tetingkap, maklumat jenis perkhidmatan dan pengisytiharan MSS daripada output kerana ia tidak menjejaskan penaakulan kami.)

1 0.0 bsdi.1102 > svr4.discard: S 1591752193:1591752193(0)
2 0.004811 (0.0048) svr4.discard > bsdi.1102: S 26368001:26368001(0)
ack 1591752194
3 0.006516 (0.0017) bsdi.1102 > svr4.buang: . ack 1

4 5.167679 (5.1612) bsdi.1102 > svr4.buang: P 1:11 (10) ack 1
5 5.201662 (0.0340) svr4.discard > bsdi.1102: . akak 11

6 194.909929 (189.7083) bsdi.1102 > svr4.buang: P 11:25 (14) ack 1
7 194.914957 (0.0050) arp siapa-ada bsdi beritahu svr4
8 194.915678 (0.0007) arp reply bsdi is-at 0:0:c0:6f:2d:40
9 194.918225 (0.0025) svr4.discard > bsdi.1102: R 26368002:26368002(0)

Rajah 18.16 Tetapkan semula sebagai tindak balas kepada ketibaan segmen data dengan sambungan separuh terbuka.

Talian 1-3 melakukan penubuhan sambungan biasa. Dalam baris 4, rentetan "hai di sana" dihantar (ini boleh diterjemahkan secara kasar sebagai "hai awak, di sana") ke pelayan buang, dalam baris 5 pengesahan diterima.

Pada ketika ini kami memutuskan sambungan kabel Ethernet daripada svr4, but semula dan menyambung semula kabel. Keseluruhan prosedur mengambil masa kira-kira 190 saat. Kemudian kami mencetak baris seterusnya input pada klien ("baris lain"), dan apabila kami menekan Return, talian itu dihantar ke pelayan (baris 6 dalam Rajah 18.16). Pada masa yang sama, respons telah diterima daripada pelayan, bagaimanapun, sejak pelayan dibut semula, cache ARPnya kosong, jadi dalam baris 7 dan 8 kita melihat permintaan dan tindak balas ARP. Kemudian set semula telah dihantar pada baris 9. Pelanggan menerima tetapan semula dan melaporkan bahawa sambungan telah ditamatkan oleh hos jauh. ( Mesej terakhir output daripada pelanggan Telnet tidaklah bermaklumat seperti yang mungkin.)

Pembukaan serentak

Ada kemungkinan untuk dua aplikasi dibuka secara aktif pada masa yang sama. SYN mesti dihantar dari setiap sisi, dan SYN ini mesti bergerak melalui rangkaian ke arah satu sama lain. Ia juga memerlukan setiap pihak mempunyai nombor port yang diketahui oleh pihak lain. Ini dipanggil terbuka serentak.

Sebagai contoh, aplikasi pada hos A dengan port tempatan 7777 sedang dibuka secara aktif ke port 8888 hos B. Aplikasi pada hos B dengan port tempatan 8888 sedang dibuka secara aktif ke port 7777 hos A.

Ini tidak sama seperti menyambungkan klien Telnet dari Hos A ke pelayan Telnet pada Hos B, manakala klien Telnet daripada Hos B menyambung ke pelayan Telnet pada Hos A. Dalam senario ini, kedua-dua pelayan Telnet melakukan buka pasif, sebaliknya daripada yang aktif, manakala pelanggan Telnet menetapkan sendiri nombor port yang diberikan secara dinamik, bukannya port yang diketahui terlebih dahulu kepada pelayan Telnet jauh.

TCP direka khusus untuk mengendalikan bukaan serentak, menghasilkan satu sambungan dan bukannya dua. (Dalam keluarga protokol lain, seperti lapisan pengangkutan OSI, ini mencipta dua sambungan dan bukannya satu.)

Apabila penemuan serentak berlaku, perubahan keadaan protokol adalah berbeza daripada yang ditunjukkan dalam Rajah 18.13. Kedua-dua hujung menghantar SYN pada masa yang sama, memasuki keadaan SYN_SENT. Apabila setiap hujung menerima SYN, keadaan berubah kepada SYN_RECEIVED ( SYN_RCVD) (lihat Rajah 18.12), dan setiap hujung menghantar semula SYN dengan pengakuan bahawa SYN telah diterima. Apabila setiap hujung menerima SYN tambah ACK, keadaan berubah kepada ESTABLISHED. Perubahan keadaan ditunjukkan dalam Rajah 18.17.

Rajah 18.17 Pertukaran segmen semasa pembukaan serentak.

Pembukaan serentak memerlukan pertukaran empat segmen, satu lebih daripada "tiga jabat tangan". Juga ambil perhatian bahawa kami tidak memanggil satu hujung pelanggan dan satu lagi pelayan, kerana dalam kes ini kedua-duanya bertindak sebagai pelanggan dan pelayan.

Ia adalah mungkin untuk menjalankan pembukaan serentak, tetapi agak sukar. Kedua-dua belah pihak harus bermula pada masa yang lebih kurang sama, supaya SYN bertindih antara satu sama lain. Dalam kes ini, masa kembali yang panjang antara kedua-dua peserta dalam sambungan boleh membantu, membolehkan SYN bertindih. Untuk mencapai matlamat ini, kami menggunakan hos bsdi sebagai satu pihak kepada sambungan dan hos vangogh.cs.berkeley.edu sebagai pihak yang lain. Memandangkan terdapat saluran SLIP dail di antara mereka, masa kembali mestilah agak besar (beberapa ratus milisaat) untuk membolehkan SYN bertindih.

Satu hujung (bsdi) menetapkan sendiri port tempatan 8888 (pilihan baris arahan -b) dan secara aktif membuka ke port 7777 hos yang lain:

bsdi % sock -v -b8888 vangogh.cs.berkeley.edu 7777
disambungkan pada 140.252.13.35.8888 hingga 128.32.130.2.7777
TCP_MAXSEG = 512
Hai dunia masukkan baris ini
dan hai di sana baris ini dicetak di hujung yang lain
sambungan ditutup oleh rakan sebaya ini adalah output apabila FIN diterima

Hujung satu lagi dimulakan pada masa yang sama, ia menetapkan sendiri nombor port tempatan 7777 dan menjalankan pembukaan aktif ke port 8888:

van Gogh % sock -v -b7777 bsdi.tuc.noao.edu 8888
disambungkan pada 128.32.130.2.7777 hingga 140.252.13.35.8888
TCP_MAXSEG = 512
hello, dunia ini dimasuki di hujung yang lain
dan hai kami mencetak baris ini
^D dan kemudian memasukkan aksara akhir fail EOF

Kami menentukan bendera -v dalam baris arahan program sock untuk menyemak alamat IP dan nombor port untuk setiap hujung sambungan. Bendera ini juga mencetak MSS yang digunakan pada setiap hujung sambungan. Kami juga mencetak satu baris sebagai input pada setiap hujung, yang dihantar ke hujung jauh dan dicetak di sana untuk memastikan kedua-dua hos "melihat" satu sama lain.

Rajah 18.18 menunjukkan pertukaran segmen untuk sambungan ini. (Kami telah mengalih keluar beberapa pilihan TCP baharu yang muncul dalam SYN asal yang datang daripada vangogh, yang menjalankan 4.4BSD. Kami akan menerangkan pilihan baharu ini dalam bahagian dalam bab ini.) Perhatikan bahawa dua SYN (baris 1 dan 2) diikuti oleh dua SYN dengan ACK (baris 3 dan 4). Dalam kes ini, pembukaan serentak berlaku.

Baris 5 menunjukkan rentetan yang dimasukkan "hello, world" yang pergi dari bsdi ke vangogh dengan pengesahan pada baris 6. Baris 7 dan 8 sepadan dengan rentetan "dan hai di sana" yang pergi ke arah lain. Baris 9-12 menunjukkan penutupan sambungan biasa.

Kebanyakan pelaksanaan Berkeley tidak menyokong pembukaan serentak dengan betul. Dalam sistem ini, jika anda boleh membuat SYN bertindih, anda akhirnya bertukar-tukar segmen, masing-masing dengan SYN dan ACK, dalam kedua-dua arah. Kebanyakan pelaksanaan tidak selalu membuat peralihan daripada keadaan SYN_SENT kepada keadaan SYN_RCVD yang ditunjukkan dalam Rajah 18.12.

1 0.0 bsdi.8888 > vangogh.7777: S 91904001:91904001(0)
menang 4096
2 0.213782 (0.2138) vangogh.7777 > bsdi.8888: S 1058199041:1058199041(0)
menang 8192
3 0.215399 (0.0016) bsdi.8888 > vangogh.7777: S 91904001:91904001(0)
ack 1058199042 menang 4096

4 0.340405 (0.1250) vangogh.7777 > bsdi.8888: S 1058199041:1058199041(0)
ack 91904002 menang 8192

5 5.633142 (5.2927) bsdi.8888 > vangogh.7777: P 1:14 (13) ack 1 menang 4096
6 6.100366 (0.4672) vangogh.7777 > bsdi.8888: . ack 14 menang 8192

7 9.640214 (3.5398) vangogh.7777 > bsdi.8888: P 1:14 (13) ack 14 menang 8192
8 9.796417 (0.1562) bsdi.8888 > vangogh.7777: . ack 14 menang 4096

9 13.060395 (3.2640) vangogh.7777 > bsdi.8888: F 14:14 (0) ack 14 menang 8192
10 13.061828 (0.0014) bsdi.8888 > vangogh.7777: . ack 15 menang 4096
11 13.079769 (0.0179) bsdi.8888 > vangogh.7777: F 14:14 (0) ack 15 menang 4096
12 13.299940 (0.2202) vangogh.7777 > bsdi.8888: . ack 15 menang 8192

Rajah 18.18Pertukaran segmen semasa pembukaan serentak.

Penutupan serentak

Seperti yang kami katakan sebelum ini, pada satu bahagian (selalunya, tetapi tidak selalu, bahagian pelanggan) penutupan aktif dilakukan dan FIN pertama dihantar. Ia juga mungkin untuk kedua-dua pihak melakukan penutupan aktif, kerana TCP membenarkan penutupan serentak.

Dari segi Rajah 18.12, kedua-dua hujung peralihan daripada keadaan ESTABLISHED kepada keadaan FIN_WAIT_1 apabila aplikasi memberi isyarat untuk ditutup. Pada masa yang sama, kedua-duanya menghantar FIN, yang mungkin ditemui di suatu tempat di rangkaian. Apabila FIN diterima, setiap hujung beralih daripada keadaan FIN_WAIT_1 ke keadaan TUTUP dan menghantar ACK akhir dari setiap hujung. Apabila setiap hujung menerima ACK akhir, keadaan berubah kepada TIME_WAIT. Rajah 18.19 menunjukkan keadaan berubah.

Rajah 18.19 Pertukaran segmen semasa penutupan serentak.

Dengan penutupan serentak, bilangan paket yang sama ditukar seperti penutupan biasa.

Pengepala TCP mungkin mengandungi pilihan (). Satu-satunya pilihan yang ditakrifkan dalam spesifikasi TCP asal ialah: akhir senarai pilihan, tiada operasi dan saiz segmen maksimum. Kami melihat dalam contoh kami pilihan MSS dalam hampir setiap segmen SYN.

RFC yang lebih baharu, seperti RFC 1323, mentakrifkan pilihan TCP tambahan, yang kebanyakannya hanya boleh didapati dalam pelaksanaan kemudian. (Kami akan menerangkan pilihan baharu dalam .) Rajah 18.20 menunjukkan format pilihan TCP semasa - yang diterangkan dalam RFC 793 dan RFC 1323.

Rajah 18.20 Pilihan TCP.

Setiap pilihan bermula dengan jenis 1-bait (jenis), yang menunjukkan jenis pilihan. Pilihan yang jenisnya ialah 0 dan 1 menduduki 1 bait. Pilihan lain mempunyai panjang bait (len) yang mengikuti bait jenis. Panjang ialah jumlah panjang, termasuk jenis dan bait panjang.

Pilihan Tiada Operasi (NOP) telah ditambahkan untuk membolehkan pengirim mengisi medan yang mesti berbilang 4 bait. Jika kami mewujudkan sambungan TCP daripada sistem 4.4BSD, pilihan berikut boleh dilihat dalam segmen SYN awal menggunakan tcpdump:

Pilihan MSS ditetapkan kepada 512, diikuti oleh NOP, diikuti dengan pilihan saiz tetingkap. Pilihan NOP pertama digunakan untuk pad pilihan saiz tetingkap 3-bait kepada 4 bait. Begitu juga, pilihan cap waktu 10-bait didahului oleh dua NOP untuk menduduki 12 bait.

Empat pilihan lain, yang mempunyai jenis 4, 5, 6, dan 7, dipanggil pilihan ACK terpilih dan pilihan gema. Kami tidak menunjukkannya dalam Rajah 18.20 kerana pilihan gema telah digantikan dengan pilihan cap waktu, dan ACK terpilih, seperti yang ditakrifkan pada masa ini, masih dalam perbincangan dan tidak dimasukkan dalam RFC 1323. Perlu diingatkan bahawa cadangan T/TCP untuk transaksi TCP (bahagian Bab 24) menentukan tiga lagi pilihan dengan jenis yang sama dengan 11, 12 dan 13.

Pelaksanaan pelayan TCP

Dalam bahagian Bab 1, kami mengatakan bahawa kebanyakan pelayan TCP adalah serentak. Apabila permintaan untuk mewujudkan sambungan baharu tiba di pelayan, ia menerima sambungan dan memulakan proses baharu yang akan melayani pelanggan baharu. Bergantung pada sistem pengendalian, kaedah berbeza digunakan untuk mencipta pelayan baharu. Pada sistem Unix, proses baharu dibuat menggunakan fungsi garpu.

Kita perlu membincangkan cara TCP berinteraksi dengan pelayan serentak. Saya ingin menjawab soalan berikut: bagaimanakah nombor port diproses apabila pelayan menerima permintaan untuk sambungan baharu daripada pelanggan, dan apakah yang berlaku jika berbilang permintaan sambungan tiba pada masa yang sama?

Nombor Port Pelayan TCP

Kita boleh mengetahui cara TCP mengendalikan nombor port dengan melihat mana-mana pelayan TCP. Mari kita lihat pelayan Telnet menggunakan arahan netstat. Output berikut adalah untuk sistem yang tidak mempunyai aktif Sambungan Telnet. (Kami telah mengalih keluar semua baris kecuali yang menunjukkan pelayan Telnet.)

matahari% netstat -a -n -f inet
Sambungan Internet aktif (termasuk pelayan)
Proto Recv-Q Send-Q Alamat Tempatan Alamat Asing (negeri)
tcp 0 0 *.23 *.* DENGAR

Bendera -a melaporkan semua titik akhir rangkaian, bukan hanya dalam keadaan ESTABLISHED. Bendera -n mencetak alamat IP dalam notasi perpuluhan angka dan bukannya menggunakan DNS untuk menukar alamat kepada nama, dan mencetak nombor port berangka (seperti 23) dan bukannya mencetak nama perkhidmatan (dalam kes ini Telnet). Pilihan -f inet melaporkan hanya titik akhir TCP dan UDP.

Alamat setempat dikeluarkan sebagai *.23, di mana asterisk biasanya dipanggil kad liar atau metacharacter. Ini bermakna permintaan sambungan masuk (SYN) akan diterima daripada mana-mana antara muka tempatan. Jika hos mempunyai berbilang antara muka, kami boleh menentukan satu alamat IP tertentu sebagai alamat IP setempat (salah satu alamat IP hos), dan hanya permintaan sambungan yang diterima daripada antara muka itu akan diservis. (Kita akan lihat bagaimana ini dilakukan kemudian dalam bahagian ini.) Port tempatan ialah 23, yang merupakan port terkenal untuk Telnet.

Alamat jauh ditunjukkan sebagai *.*, yang bermaksud bahawa alamat IP jauh dan nombor port jauh belum diketahui kerana titik akhir berada dalam keadaan LISTEN, menunggu permintaan sambungan tiba.

Sekarang kami memulakan pelanggan Telnet pada hos slip (140.252.13.65), yang akan menyambung ke pelayan ini. Berikut ialah baris output yang sepadan daripada arahan netstat:


tcp 0 0 140.252.13.33.23 140.252.13.65.1029 DITUBUHKAN
tcp 0 0 *.23 *.* DENGAR

Baris pertama untuk port 23 ialah sambungan yang telah ditetapkan(DITUBUHKAN). Untuk sambungan ini, kesemua empat elemen alamat tempatan dan jauh diisi: alamat IP tempatan dan nombor port, dan alamat IP jauh dan nombor port. Alamat IP tempatan sepadan dengan antara muka di mana permintaan sambungan tiba (antara muka Ethernet, 140.252.13.33).

Titik akhir kekal dalam keadaan LISTEN. Ini ialah titik akhir yang digunakan oleh pelayan serentak untuk menerima permintaan sambungan yang akan datang pada masa hadapan. Dalam kes ini, modul TCP yang berada dalam kernel mencipta titik akhir baharu dalam keadaan ESTABLISHED apabila permintaan sambungan masuk tiba dan diterima. Juga ambil perhatian bahawa nombor port untuk sambungan yang berada dalam keadaan ESTABLISHED tidak berubah: ia adalah 23, sama seperti untuk titik akhir yang berada dalam keadaan LISTEN.

Sekarang kami memulakan pelanggan Telnet lain dari klien yang sama (slip) ke pelayan ini. Output yang sepadan daripada arahan netstat akan kelihatan seperti ini:

Proto Recv-Q Send-Q Alamat Tempatan Alamat Asing (negeri)
tcp 0 0 140.252.13.33.23 140.252.13.65.1030 DITUBUHKAN
tcp 0 0 140.252.13.33.23 140.252.13.65.1029 DITUBUHKAN
tcp 0 0 *.23 *.* DENGAR

Sekarang kita melihat dua sambungan yang telah ditetapkan (TERBENTUK) dari hos yang sama ke pelayan yang sama. Kedua-duanya mempunyai nombor port tempatan 23. Ini bukan masalah untuk TCP, kerana nombor port jauh berbeza. Mereka mesti berbeza kerana setiap pelanggan Telnet menggunakan port yang diperuntukkan secara dinamik, dan daripada definisi port yang diperuntukkan secara dinamik, kita tahu bahawa hanya port yang tidak digunakan pada masa ini pada hos (slip) boleh ditetapkan secara dinamik.

Contoh ini menunjukkan bahawa TCP menyahmultipleks segmen masuk menggunakan keempat-empat nilai, yang dibandingkan dengan tempatan dan alamat jauh: Alamat IP destinasi, nombor port destinasi, alamat IP sumber dan nombor port sumber. TCP tidak boleh menentukan proses yang menerima segmen masuk dengan hanya melihat pada nombor port destinasi. Selain itu, hanya satu daripada tiga titik akhir pada port 23, yang berada dalam keadaan LISTEN, menerima permintaan sambungan masuk. Titik akhir dalam keadaan ESTABLISHED tidak boleh menerima segmen SYN dan titik akhir dalam keadaan LISTEN tidak boleh menerima segmen data.

Kini kami memulakan pelanggan Telnet lain daripada hos solar, yang akan melalui saluran SLIP dari matahari, dan bukannya melalui Ethernet.

Proto Recv-Q Send-Q Alamat Tempatan Alamat Asing (negeri)
tcp 0 0 140.252.1.29.23 140.252.1.32.34603 DITUBUHKAN
tcp 0 0 140.252.13.33.23 140.252.13.65.1030 DITUBUHKAN
tcp 0 0 140.252.13.33.23 140.252.13.65.1029 DITUBUHKAN
tcp 0 0 *.23 *.* DENGAR

Alamat IP tempatan untuk sambungan pertama yang ditubuhkan (ESTABLISHED) kini sepadan dengan alamat antara muka saluran SLIP pada matahari hos berbilang antara muka (140.252.1.29).

Mengehadkan alamat IP tempatan

Kita boleh melihat apa yang berlaku apabila pelayan tidak menggunakan kad bebas sebagai alamat IP tempatannya, sebaliknya menetapkan kepada satu alamat antara muka tempatan tertentu. Jika kami memberikan alamat IP (atau nama hos) kepada program stoking kami apabila kami menggunakannya sebagai pelayan, alamat IP tersebut menjadi alamat IP tempatan titik akhir mendengar. Sebagai contoh

matahari% stokin -s 140.252.1.29 8888

mengehadkan pelayan ini kepada hanya sambungan yang datang daripada antara muka SLIP (140.252.1.29). Output arahan netstat akan menunjukkan perkara berikut:

Proto Recv-Q Send-Q Alamat Tempatan Alamat Asing (negeri)

Jika kami menyambung ke pelayan ini melalui saluran SLIP daripada hos solar, ia akan berfungsi.

Proto Recv-Q Send-Q Alamat Tempatan Alamat Asing (negeri)
tcp 0 0 140.252.1.29.8888 140.252.1.32.34614 DITUBUHKAN
tcp 0 0 140.252.1.29.8888 *.* DENGAR

Walau bagaimanapun, jika kami cuba menyambung ke pelayan ini daripada hos melalui Ethernet (140.252.13), permintaan sambungan tidak akan diterima oleh modul TCP. Jika kita melihat menggunakan tcpdump, kita akan melihat bahawa respons RST diterima pada SYN, seperti yang ditunjukkan dalam Rajah 18.21.

1 0.0 bsdi.1026 > matahari.8888: S 3657920001:3657920001(0)
menang 4096
2 0.000859 (0.0009) matahari.8888 > bsdi.1026: R 0:0 (0) ack 3657920002 menang 0

Rajah 18.21 Mengehadkan permintaan sambungan berdasarkan alamat IP tempatan pelayan.

Aplikasi yang berjalan pada pelayan tidak akan pernah melihat permintaan sambungan - sekatan dijalankan oleh modul TCP dalam kernel berdasarkan alamat IP tempatan yang ditentukan oleh aplikasi.

Sekatan Alamat IP Jauh

Dalam bahagian Bab 11, kami melihat bahawa pelayan UDP boleh menentukan alamat IP jauh dan nombor port, sebagai tambahan kepada alamat IP tempatan dan nombor port yang ditentukan. Fungsi antara muka yang dinyatakan dalam RFC 793 membolehkan pelayan melakukan buka pasif berdasarkan soket jauh yang ditentukan sepenuhnya (dalam hal ini permintaan terbuka aktif daripada klien tertentu dijangka) atau soket jauh yang tidak ditentukan (dalam hal ini permintaan sambungan daripada mana-mana pelanggan dijangka).

Malangnya, kebanyakan API tidak menyediakan keupayaan sedemikian. Pelayan mesti membiarkan soket jauh tanpa segera, menunggu sambungan tiba, dan kemudian menyemak alamat IP dan nombor port pelanggan.

Rajah 18.22 menunjukkan tiga jenis alamat dan perhubungan alamat-ke-port yang pelayan TCP boleh tetapkan untuk dirinya sendiri. Dalam semua kes, lport ialah port yang diketahui oleh pelayan, dan localIP mestilah alamat IP antara muka tempatan. Susunan di mana tiga baris muncul dalam jadual sepadan dengan susunan modul TCP cuba untuk menentukan titik akhir setempat yang akan menerima permintaan sambungan masuk. Baris pertama jadual (jika disokong) dicuba dahulu, dan kemudian spesifikasi yang selebihnya (baris terakhir dengan alamat IP yang ditentukan sebagai kad bebas) cuba terakhir.

Rajah 18.22 Menentukan alamat IP tempatan dan jauh serta nombor port untuk pelayan TCP.

Barisan permintaan sambungan masuk

Pelayan serentak memulakan proses baharu yang melayani setiap pelanggan, jadi pelayan mendengar mesti sentiasa bersedia untuk mengendalikan permintaan sambungan masuk seterusnya. Inilah sebab utama mengapa pelayan kompetitif digunakan. Walau bagaimanapun, ada kemungkinan bahawa berbilang permintaan sambungan akan tiba semasa pelayan mendengar sedang mencipta proses baharu atau semasa sistem pengendalian sedang sibuk memproses satu lagi proses keutamaan yang lebih tinggi. Bagaimanakah TCP mengendalikan permintaan sambungan masuk ini semasa aplikasi mendengar sibuk?

Pelaksanaan Berkeley menggunakan peraturan berikut.

  1. Setiap titik akhir mendengar mempunyai baris gilir sambungan panjang tetap yang boleh diterima oleh TCP ("jabat tangan tiga kali" selesai) tetapi belum lagi diterima oleh aplikasi. Berhati-hati untuk membezakan antara menerima sambungan TCP dan meletakkannya dalam baris gilir dan aplikasi yang menerima sambungan daripada baris gilir itu.
  2. Aplikasi ini menetapkan had atau had untuk baris gilir ini, yang biasanya dipanggil tunggakan. Had ini hendaklah dalam julat dari 0 hingga 5. (Kebanyakan aplikasi menyatakan nilai maksimum 5.)
  3. Apabila permintaan sambungan (segmen SYN) tiba, TCP melihat bilangan sambungan semasa yang sedang beratur untuk titik akhir pendengaran itu dan ia menentukan sama ada sambungan itu boleh diterima. Kami menjangkakan nilai tunggakan itu ditentukan oleh aplikasi, akan menjadi maksimum, iaitu, bilangan maksimum sambungan untuk titik ini dibenarkan untuk beratur, walaupun ini tidak begitu mudah. Rajah 18.23 menunjukkan hubungan antara nilai tunggakan dan bilangan maksimum sebenar sambungan yang boleh digilir pada sistem Berkeley tradisional dan Solaris 2.2.

    nilai tunggakan

    Jumlah maksimum sambungan beratur

    BSD tradisional

    Rajah 18.23 Bilangan maksimum sambungan yang diterima untuk titik akhir mendengar.

    Ingat bahawa nilai tunggakan ini hanya menunjukkan bilangan maksimum sambungan yang beratur untuk satu titik akhir pendengaran, yang kesemuanya telah diterima oleh TCP dan sedang menunggu untuk diterima oleh aplikasi. Nilai tunggakan tidak mempunyai sebarang kesan ke atas bilangan maksimum sambungan yang boleh diwujudkan oleh sistem atau bilangan pelanggan yang pelayan serentak boleh berkhidmat.

    Nilai untuk Solaris dalam angka ini adalah tepat seperti yang kami jangkakan. Nilai tradisional untuk BSD (atas sebab yang tidak diketahui) adalah sama dengan nilai tunggakan kali 3 dibahagikan dengan 2 tambah 1.

  4. Jika terdapat ruang dalam baris gilir untuk titik akhir pendengaran yang diberikan untuk sambungan baharu (lihat Rajah 18.23), modul TCP mengakui (ACK) SYN yang masuk dan mewujudkan sambungan. Aplikasi pelayan dengan titik akhir mendengar tidak akan melihat sambungan baharu ini sehingga segmen ketiga "jabat tangan tiga kali" diterima. Sebagai alternatif, pelanggan boleh menganggap pelayan bersedia untuk menerima data apabila pembukaan aktif klien telah berjaya diselesaikan, sebelum aplikasi pelayan dimaklumkan tentang sambungan baharu. (Jika ini berlaku, pelayan TCP hanya akan beratur data masuk.)
  5. Jika tidak ada ruang yang mencukupi untuk beratur sambungan baharu, TCP hanya mengabaikan SYN yang diterima. Tiada apa-apa dihantar sebagai balasan (malah segmen RST tidak dihantar). Jika pelayan mendengar tidak boleh menolak untuk menerima beberapa sambungan yang telah diterima yang telah mengisi baris gilir mengikut kapasiti, buka aktif klien akan tamat masa.

Kita boleh melihat skrip ini menggunakan program sock. Mari jalankannya dengan pilihan baharu ( -O) yang memberitahu kami untuk berhenti seketika selepas membuat titik akhir mendengar, sebelum menerima sebarang permintaan sambungan. Jika kami kemudian memulakan berbilang pelanggan semasa jeda ini, pelayan akan dipaksa untuk beratur untuk sambungan yang diterima dan kami akan melihat apa yang berlaku menggunakan perintah tcpdump.

bsdi % stokin -s -v -q1 -O30 5555

Pilihan -q1 menetapkan tunggakan titik akhir pendengaran kepada 1, yang pada sistem BSD tradisional akan sepadan dengan dua permintaan sambungan (Rajah 18.23). Pilihan -O30 menyebabkan program "tidur" selama 30 saat sebelum menerima sebarang sambungan daripada klien. Ini memberi kami 30 saat untuk memulakan beberapa pelanggan yang akan mengisi baris gilir. Kami memulakan empat pelanggan di matahari tuan rumah.

Rajah 18.24 menunjukkan output program tcpdump, output ini bermula dengan SYN pertama daripada klien pertama. (Kami telah mengalih keluar pengisytiharan saiz tetingkap dan pengisytiharan MSS. Kami juga telah menyerlahkan nombor port klien dalam huruf tebal apabila sambungan TCP diwujudkan - "jabat tangan tiga kali".)

Permintaan sambungan pertama daripada klien, datang dari port 1090, diterima oleh modul TCP (segmen 1-3). Permintaan sambungan kedua daripada klien pada port 1091 juga diterima oleh modul TCP (segmen 4-6). Aplikasi pelayan masih tidur dan tidak menerima sebarang sambungan. Semua yang dilakukan telah dilakukan oleh modul TCP dalam kernel. Perlu juga diperhatikan bahawa dua pelanggan berjaya melakukan pembukaan aktif, iaitu, "jabat tangan tiga kali" berjaya diselesaikan.

1 0.0 matahari. 1090 > bsdi.7777: S 1617152000:1617152000(0)
2 0.002310 (0.0023) bsdi.7777 > matahari. 1090 : S 4164096001:4164096001(0)
3 0.003098 (0.0008) matahari. 1090 > bsdi.7777: . ack 1617152001
ack 1
4 4.291007 (4.2879) matahari. 1091 > bsdi.7777: S 1617792000:1617792000(0)
5 4.293349 (0.0023) bsdi.7777 > matahari. 1091 : S 4164672001:4164672001(0)
ack 1617792001
6 4.294167 (0.0008) matahari. 1091 > bsdi.7777: . ack 1
7 7.131981 (2.8378) matahari.1092 >
8 10.556787 (3.4248) matahari.1093 > bsdi.7777: S 1618688000:1618688000(0)
9 12.695916 (2.1391) matahari.1092 > bsdi.7777: S 1618176000:1618176000(0)
10 16.195772 (3.4999) matahari.1093 >
11 24.695571 (8.4998) matahari.1092 > bsdi.7777: S 1618176000:1618176000(0)
12 28.195454 (3.4999) matahari. 1093 > bsdi.7777: S 1618688000:1618688000(0)
13 28.197810 (0.0024) bsdi.7777 > matahari. 1093 : S 4167808001:4167808001(0)
14 28.198639 (0.0008) matahari. 1093 > bsdi.7777: . ack 1618688001
ack 1
15 48.694931 (20.4963) matahari. 1092 > bsdi.7777: S 1618176000:1618176000(0)
16 48.697292 (0.0024) bsdi.7777 > matahari. 1092 : S 4170496001:4170496001(0)
ack 1618176001
17 48.698145 (0.0009) matahari. 1092 > bsdi.7777: . ack 1

Rajah 18.24 Output daripada tcpdump untuk contoh penggunaan backlog.

Kami cuba memulakan pelanggan ketiga pada segmen 7 (port 1092) dan yang keempat pada segmen 8 (port 1093). TCP mengabaikan kedua-dua SYN kerana baris gilir untuk titik akhir mendengar itu penuh. Kedua-dua pelanggan menghantar semula SYN mereka dalam segmen 9, 10, 11, 12 dan 15. Penghantaran semula ketiga pelanggan keempat diterima (segmen 12-14) kerana jeda 30 saat pelayan telah tamat dan pelayan telah melepaskan dua sambungan yang diterima. membersihkan baris gilir. (Sebab ini berlaku ialah sambungan ini diterima oleh pelayan pada masa 28.19, dan bukan pada masa yang lebih besar daripada 30; ini berlaku kerana ia mengambil masa beberapa saat untuk memulakan klien pertama [segmen 1 , masa mula dalam output] selepas pelayan bermula.) Penghantaran semula keempat klien ketiga juga diterima (segmen 15-17). Sambungan klien keempat (port 1093) telah diterima oleh pelayan sebelum sambungan klien ketiga (port 1092) disebabkan oleh kebetulan masa antara penghujung jeda 30 saat dan penghantaran semula pelanggan.

Kami boleh menjangkakan baris gilir sambungan yang diterima akan diproses oleh aplikasi mengikut prinsip FIFO (masuk dahulu, keluar dahulu). Oleh itu, selepas TCP menerima aplikasi pada port 1090 dan 1091, kami menjangkakan aplikasi menerima sambungan terlebih dahulu pada port 1090 dan kemudian sambungan pada port 1091. Walau bagaimanapun, terdapat pepijat dalam kebanyakan pelaksanaan Berkeley yang mengakibatkan penggunaan tertib LIFO (masuk terakhir, keluar dahulu). Pengilang telah mencuba berkali-kali untuk membetulkan pepijat ini, tetapi ia masih wujud dalam sistem seperti SunOS 4.1.3.

TCP mengabaikan SYN masuk apabila baris gilir penuh dan tidak bertindak balas menggunakan RST kerana ralat. Biasanya baris gilir penuh kerana aplikasi atau sistem pengendalian sibuk, jadi aplikasi tidak dapat memproses sambungan masuk. Keadaan ini boleh berubah dalam tempoh yang singkat. Walau bagaimanapun, jika pelayan TCP bertindak balas dengan tetapan semula, pembukaan aktif klien akan terganggu (inilah yang akan berlaku jika pelayan belum dimulakan). Oleh kerana SYN diabaikan, pelanggan TCP akan dipaksa untuk menghantar semula SYN kemudian, dengan harapan akan ada ruang dalam baris gilir untuk sambungan baharu.

Pada ketika ini adalah perlu untuk membincangkan satu lagi perincian penting, yang terdapat dalam hampir semua pelaksanaan TCP/IP. Ia adalah bahawa TCP menerima permintaan sambungan masuk (SYN) jika terdapat ruang dalam baris gilir. Dalam kes ini, aplikasi tidak dapat melihat dari siapa permintaan itu (alamat IP sumber dan nombor port sumber). Ini tidak diperlukan oleh TCP, ia hanyalah teknik umum yang digunakan dalam pelaksanaan. Jika API, seperti TLI (bahagian Bab 1), memberitahu aplikasi bahawa permintaan sambungan telah tiba dan membenarkan aplikasi untuk memilih sama ada untuk menerima sambungan atau tidak, maka apabila menggunakan TCP ia adalah supaya apabila aplikasi diberitahu bahawa sambungan baru sahaja tiba, sebenarnya TCP telah pun menyelesaikan "jabat tangan tiga kali"! Dalam lapisan pengangkutan lain adalah mungkin untuk membezakan antara sambungan yang tiba dan yang diterima (OSI lapisan pengangkutan), namun TCP tidak menyediakan ciri ini.

Solaris 2.2 menyediakan pilihan yang menghalang TCP daripada menerima permintaan sambungan masuk sehingga aplikasi membenarkannya berbuat demikian (tcp_eager_listeners dalam bahagian aplikasi E).

Tingkah laku ini juga bermakna pelayan TCP tidak boleh menyebabkan klien aktif terbuka terganggu. Apabila sambungan daripada klien baharu sampai ke aplikasi pelayan, "jabat tangan tiga hala" TCP telah pun selesai dan penemuan aktif klien telah berjaya diselesaikan. Jika pelayan kemudian melihat alamat IP dan nombor port pelanggan dan memutuskan bahawa ia tidak mahu melayani pelanggan itu, semua pelayan hanya boleh menutup sambungan (yang akan menghantar FIN) atau menetapkan semula sambungan (yang akan menghantar RST) . Walau apa pun, pelanggan akan menganggap bahawa semuanya baik-baik saja dengan pelayan, kerana pembukaan aktif telah selesai, dan, kemungkinan besar, telah menghantar beberapa jenis permintaan kepada pelayan.

Kesimpulan ringkas

Sebelum dua proses boleh berkomunikasi menggunakan TCP, mereka mesti mewujudkan sambungan antara satu sama lain. Apabila kerja di antara mereka selesai, sambungan harus diputuskan. Bab ini memperincikan cara sambungan diwujudkan menggunakan "jabat tangan tiga hop" dan cara ia diputuskan menggunakan jabat tangan empat lompatan.

Kami menggunakan tcpdump untuk menunjukkan semua medan dalam pengepala TCP. Kami juga melihat bagaimana sambungan yang telah ditetapkan boleh ditamatkan masa, cara sambungan ditetapkan semula, apa yang berlaku kepada sambungan separuh terbuka, dan cara TCP menyediakan mod separuh tertutup, pembukaan serentak dan penutupan serentak.

Untuk memahami fungsi TCP, adalah perlu untuk mempertimbangkan rajah keadaan TCP asas. Kami meneliti titik demi titik cara sambungan diwujudkan dan ditamatkan, dan perubahan dalam keadaan yang berlaku semasa proses ini. Kami juga melihat bagaimana pelayan TCP mewujudkan sambungan TCP.

Sambungan TCP dikenal pasti secara unik melalui 4 parameter: alamat IP tempatan, nombor port tempatan, alamat IP jauh dan nombor port jauh. Jika sambungan terputus, satu pihak mesti masih mengingati sambungan itu, dalam hal ini kami mengatakan bahawa mod TIME_WAIT sedang berkuat kuasa. Peraturan menyatakan bahawa pihak ini boleh melakukan buka aktif dengan memasuki mod ini selepas dua kali masa MSL yang diterima untuk pelaksanaan ini telah tamat tempoh.

Senaman

  1. Dalam bahagian itu, kami berkata bahawa nombor jujukan awal (ISN) biasanya ditetapkan kepada 1 dan dinaikkan sebanyak 64000 setiap setengah saat dan setiap kali terdapat pembukaan aktif. Ini bermakna bahawa tiga digit paling ketara dalam ISN akan sentiasa 001. Walau bagaimanapun, dalam Rajah 18.3, tiga digit terendah untuk setiap arah ialah 521. Bagaimanakah ini berlaku?
  2. Dalam Rajah 18.15, kami mencetak 12 aksara, tetapi melihat bahawa TCP menghantar 13 bait. Dalam Rajah 18.16, kami mencetak 8 aksara, tetapi TCP menghantar 10 bait. Mengapakah 1 bait ditambahkan dalam kes pertama, dan 2 bait dalam kes kedua?
  3. Apakah perbezaan antara sambungan separuh terbuka dan sambungan separuh tertutup?
  4. Jika kita memulakan program sock sebagai pelayan, dan kemudian mengganggu operasinya (tanpa pelanggan disambungkan kepadanya), kita boleh segera memulakan semula pelayan. Ini bermakna ia tidak akan berada dalam keadaan menunggu 2MSL. Terangkan perkara ini dari segi rajah peralihan keadaan.
  5. Dalam bahagian kami menunjukkan bahawa pelanggan tidak boleh menggunakan semula nombor port tempatan yang sama manakala port adalah sebahagian daripada sambungan dalam keadaan menunggu 2MSL. Walau bagaimanapun, jika kami menjalankan program sock dua kali berturut-turut sebagai pelanggan yang menyambung ke pelayan masa, kami boleh menggunakan nombor port tempatan yang sama. Selain itu, kita boleh membuat sambungan baharu yang akan berada dalam keadaan menunggu 2MSL. Bagaimana ini berlaku?

    matahari% stokin -v bsdi siang hari

    Rabu 7 Julai 07:54:51 1993
    sambungan ditutup oleh rakan sebaya

    matahari% stokin -v -b1163 bsdi siang hari guna semula nombor port tempatan yang sama
    disambungkan pada 140.252.13.33.1163 hingga 140.252.13.35.13
    Rabu 7 Julai 07:55:01 1993
    sambungan ditutup oleh rakan sebaya

  6. Pada penghujung bahagian, apabila kami menerangkan keadaan FIN_WAIT_2, kami menyatakan bahawa kebanyakan pelaksanaan akan mengalihkan sambungan dari keadaan ini ke keadaan TUTUP jika aplikasi telah menyelesaikan penutupan penuh (bukan separuh tertutup) selepas kira-kira 11 minit. Jika pihak lain (dalam keadaan CLOSE_WAIT) menunggu 12 minit sebelum melakukan penutupan (menghantar FINnya), apakah yang akan diterima oleh TCPnya sebagai tindak balas kepada FIN?
  7. Pihak manakah dalam perbualan telefon melakukan pembukaan aktif dan yang manakah membuka pembukaan pasif? Adakah pembukaan serentak mungkin? Adakah mungkin untuk ditutup pada masa yang sama?
  8. Dalam Rajah 18.6 kami tidak melihat permintaan ARP atau respons ARP. Walau bagaimanapun, alamat perkakasan hos svr4 mestilah dalam cache ARP bsdi. Apakah yang akan berubah dalam gambar ini jika item ini tiada dalam cache ARP?
  9. Terangkan output berikut daripada arahan tcpdump. Bandingkan dengan Rajah 18.13.

    1 0.0 solaris.32990 > bsdi.discard: S 40140288:40140288 (0)
    menang 8760
    2 0.003295 (0.0033) bsdi.discard > solaris.32990: S 4208081409:4208081409 (0)
    ack 40140289 menang 4096

    3 0.419991 (0.4167) solaris.32990 > bsdi.buang: P 1:257 (256) ack 1 menang 9216
    4 0.449852 (0.0299) solaris.32990 > bsdi.buang: F 257:257 (0) ack 1 menang 9216
    5 0.451965 (0.0021) bsdi.discard > solaris.32990: . ack 258 menang 3840
    6 0.464569 (0.0126) bsdi.discard > solaris.32990: F 1:1 (0) ack 258 menang 4096
    7 0.720031 (0.2555) solaris.32990 > bsdi.buang: . ack 2 menang 9216

  10. Mengapakah pelayan dalam Rajah 18.4 tidak menggabungkan ACK kepada FIN pelanggan dengan FINnya sendiri, dengan itu mengurangkan bilangan segmen kepada tiga?
  11. Dalam Rajah 18.16, mengapakah urutan RST nombor 26368002?
  12. Beritahu saya, adakah permintaan TCP kepada lapisan pautan untuk MTUnya berdasarkan prinsip pelapisan?
  13. demultipleks berdasarkan nombor port Destinasi TCP. Betulkah?

Protokol Kawalan Penghantaran (TCP) adalah salah satu yang utama protokol rangkaian Internet, direka untuk mengawal penghantaran data dalam rangkaian dan subnet TCP/IP.

1) Mari kita ingat model OSI


Tempat TCP dalam model OSI diduduki oleh lapisan 4 dan 5:

TCP ialah mekanisme pengangkutan yang menyediakan aliran data, Dengan pra-pemasangan sambungan, disebabkan ini, ia memberikan keyakinan terhadap kebolehpercayaan data yang diterima, membuat permintaan berulang untuk data sekiranya kehilangan data dan menghapuskan pertindihan apabila menerima dua salinan pakej yang sama. Tidak seperti UDP, ia menjamin integriti data yang dihantar dan memberitahu penghantar hasil pemindahan.


Pelaksanaan TCP biasanya dibina ke dalam kernel OS, walaupun terdapat juga pelaksanaan TCP dalam konteks aplikasi.

Apabila memindahkan dari komputer ke komputer melalui Internet, TCP beroperasi di lapisan atas antara kedua-duanya sistem akhir, sebagai contoh, pelayar dan pelayan web. TCP juga boleh memindahkan aliran bait dari satu program pada beberapa komputer ke program lain pada komputer lain. E-mel dan program perkongsian fail menggunakan TCP.
Pemantau TCP =

  1. panjang mesej
  2. kelajuan mesej
  3. trafik rangkaian.

Struktur pengepala TCP:


atau anda boleh mengkaji gambar glamor ini:

bendera:

Nombor urutan

Nombor urutan mempunyai dua tujuan:

Jika bendera SYN ditetapkan, maka ini ialah nilai awal nombor jujukan - ISN (Nombor Urutan Permulaan), dan bait pertama data yang akan dihantar dalam paket seterusnya akan mempunyai nombor jujukan yang sama dengan ISN + 1.
Jika tidak, jika SYN tidak ditetapkan, bait pertama data yang dihantar dalam paket tertentu mempunyai nombor urutan ini.

Memandangkan strim TCP biasanya boleh lebih panjang daripada bilangan keadaan berbeza medan ini, semua operasi dengan nombor jujukan mesti dilakukan modulo 2^32. Ini meletakkan had praktikal pada penggunaan TCP. Jika kelajuan pemindahan sistem perhubungan adalah sedemikian rupa sehingga semasa MSL (seumur hidup segmen maksimum) nombor jujukan melimpah, kemudian dua segmen dengan nombor yang sama mungkin muncul dalam rangkaian, kepunyaan bahagian strim yang berbeza, dan penerima akan menerima data yang salah.
Nombor pengesahan

Jika bendera ACK ditetapkan, medan ini mengandungi nombor urutan yang dijangkakan oleh penerima pada kali seterusnya. Tandakan segmen ini sebagai pengesahan penerimaan.
Data mengimbangi

Medan ini menentukan saiz pengepala paket TCP dalam perkataan 4-bait (4-oktet). Saiz minimum ialah 5 perkataan dan maksimum ialah 15, iaitu 20 dan 60 bait masing-masing. Offset dikira dari permulaan pengepala TCP.
Terpelihara

Dipelihara (6 bit) untuk kegunaan masa hadapan dan mesti ditetapkan kepada sifar. Daripada jumlah ini, dua (ke-5 dan ke-6) telah ditakrifkan:

CWR (Congestion Window Reduced) - Congestion Window Reduced field - bendera ditetapkan oleh penghantar untuk menunjukkan bahawa paket telah diterima dengan set bendera ECE (RFC 3168)
ECE (ECN-Echo) - Medan ECN Echo - menunjukkan bahawa nod ini mampu ECN (Pemberitahuan Kesesakan Eksplisit) dan untuk menunjukkan kepada pengirim tentang kesesakan rangkaian (RFC 3168)

Bendera (bit kawalan)

Medan ini mengandungi bendera 6 bit:

URG - Medan penunjuk segera adalah penting
ACK - Medan pengiktirafan adalah penting
PSH - (fungsi Tekan Bahasa Inggeris) mengarahkan penerima untuk menolak data terkumpul dalam penimbal penerima ke dalam aplikasi pengguna
RST - Tamatkan sambungan, tetapkan semula penimbal (pembersihan penimbal) (ms. Tetapkan semula sambungan)
SYN - Segerakkan nombor jujukan
FIN (akhir bahasa Inggeris, bit) - bendera, apabila ditetapkan, menunjukkan penamatan sambungan (bit FIN Inggeris digunakan untuk penamatan sambungan).

Medan ini mengandungi nombor yang menentukan, dalam bait, saiz data yang sanggup diterima oleh pengirim.

Mekanisme protokol

Mekanisme protokol

Tidak seperti alternatif tradisional, UDP, yang boleh mula menghantar paket dengan serta-merta, TCP mewujudkan sambungan yang mesti dibuat sebelum menghantar data. Sambungan TCP boleh dibahagikan kepada 3 peringkat:

  1. Mewujudkan sambungan
  2. Pemindahan data
  3. Menamatkan sambungan

Dalam hubungan ini, kita boleh bercakap tentang keadaan sesi TCP:

Sesi TCP menyatakan: