Bisakah paket TCP dan UDP dipecah menjadi beberapa bagian?

41

Bisakah paket TCP tiba ke penerima demi bagian?

Misalnya, jika saya mengirim 20 byte menggunakan protokol TCP, dapatkah saya 100% yakin bahwa saya akan menerima tepat 20 byte sekaligus, bukan 10 byte kemudian 10 byte lagi atau lebih?

Dan pertanyaan yang sama untuk protokol UDP.
Saya tahu bahwa UDP tidak dapat diandalkan dan paket tidak dapat tiba sama sekali atau tiba dalam urutan yang berbeda, tetapi bagaimana dengan satu paket? Jika tiba, bisakah saya yakin itu paket lengkap, bukan sepotong?

iamnp
sumber
7
Titik klarifikasi: Ini disebut segmen TCP dan datagram UDP. Mereka bukan paket. TCP = Segmen, UDP = Datagram, IP = Paket, Ethernet = Bingkai, Di semua lapisan lainnya (AFAIK) mereka hanya disebut PDU's (Protocol Data Unit).
joeqwerty

Jawaban:

33

dapatkah paket TCP tiba ke penerima demi bagian?

Iya nih. IP mendukung fragmentasi, meskipun TCP umumnya mencoba menentukan jalur MTU dan menjaga paketnya lebih kecil dari itu untuk alasan kinerja. Fragmentasi meningkatkan tingkat kehilangan datagram serempak. Jika jalur memiliki tingkat kehilangan paket 10%, memecah datagram menjadi dua paket membuat tingkat kehilangan datagram hampir 20%. (Jika salah satu paket hilang, datagram hilang.)

Anda tidak perlu khawatir tentang ini, dan juga lapisan TCP. Lapisan IP merakit kembali paket menjadi seluruh datagram.

Misalnya: jika saya mengirim 20 byte menggunakan protokol TCP, dapatkah saya 100% yakin bahwa saya akan menerima tepat 20 byte sekaligus, bukan 10 byte kemudian 10 byte lagi atau lebih?

Tidak, tapi itu tidak ada hubungannya dengan paket. TCP, pada dasarnya, adalah protokol byte stream yang tidak mempertahankan batas-batas pesan aplikasi.

Dan pertanyaan yang sama untuk protokol UDP. Saya tahu bahwa UDP tidak dapat diandalkan dan paket tidak dapat tiba sama sekali atau tiba dalam urutan yang berbeda,

Hal yang sama berlaku untuk TCP. Paket adalah paket. Perbedaannya adalah bahwa TCP telah mencoba ulang dan menyusun ulang yang dibangun ke dalam protokol sedangkan UDP tidak.

tapi bagaimana dengan 1 paket? Jika tiba, dapatkah saya yakin itu paket lengkap, bukan sepotong?

Tidak, tapi itu bukan masalahmu. Protokol UDP menangani perakitan kembali datagram. Itu bagian dari tugasnya. (Pada kenyataannya, protokol IP melakukan ini untuk protokol UDP, jadi UDP melakukannya hanya dengan dilapiskan di atas IP.) Jika datagram terbagi menjadi dua paket, protokol IP akan menyusun kembali untuk protokol UDP, sehingga Anda akan melihat data lengkap.

David Schwartz
sumber
10
Mungkin layak untuk mengklarifikasi bit terakhir untuk pembaca pemula: Anda akan melihat data lengkap untuk datagram yang dimaksud . Jika salah satu dari paket split hilang, datagram hilang dan lapisan UDP tidak akan pernah mengetahuinya. Selama semua paket dalam datagram diterima, mereka akan dirakit pada lapisan IP dan kemudian diteruskan ke lapisan UDP. Ini tidak menghalangi kemungkinan hilangnya "potongan" dalam datastream. Bukan untuk menjadi pedant, tetapi ketika saya belajar hal ini saya tidak grok perbedaan antara IP frag dan kehilangan UDP sampai 2 atau 3 melewati buku teks.
Justin ᚅᚔᚈᚄᚒᚔ
20

Anda tidak dapat memastikan bahwa mereka benar-benar tiba secara fisik sekaligus. Lapisan tautan Data di bawah TCP / UDP mungkin membagi paket Anda jika mereka mau. Terutama jika Anda mengirim data melalui internet atau jaringan apa pun di luar kendali Anda, sulit untuk diprediksi.

Tetapi tidak masalah apakah datanya tiba dalam satu paket atau beberapa paket di penerima. OS harus mengabstraksi penyatuan paket-paket ini, jadi untuk aplikasi Anda, sepertinya semuanya tiba sekaligus. Jadi, kecuali Anda adalah peretas kernel, dalam banyak kasus Anda tidak perlu khawatir jika data ini ditransfer dalam satu atau banyak paket.

Untuk UDP OS juga akan melakukan beberapa abstraksi, sehingga aplikasi yang menerima data tidak harus tahu berapa banyak paket data yang telah dikirimkan. Tetapi perbedaan TCP adalah bahwa tidak ada jaminan untuk data benar-benar tiba. Mungkin juga bahwa data dibagi menjadi beberapa paket, dan beberapa di antaranya tiba dan sebagian tidak. Untuk aplikasi penerima itu tetap saja tampak seperti aliran data, tidak masalah apakah itu lengkap atau tidak.

ulangan
sumber
Bukankah driver kartu jaringan menangani pemasangan kembali paket bukan kernel?
bluehallu
2
@Hallucynogenyc: Kecuali jika ada perubahan, protokol Internet dirancang untuk memungkinkan paket lebih dari 576 byte untuk dibagi pada setiap titik dalam perjalanan mereka, tetapi tidak mengharapkan apa-apa selain penerima akhir untuk menggabungkannya kembali. Saya pikir idenya adalah bahwa penggunaan paket yang lebih besar dalam banyak kasus merupakan upaya untuk mengurangi overhead; begitu suatu paket telah terpecah pada suatu titik dalam perjalanannya, biaya overhead telah dikeluarkan sehingga mengkombinasikan sebelum penerima akhir tidak bisa membantu apa pun, dan mungkin terluka jika harus dipecah kembali.
supercat
Saya percaya bahwa sementara paket apa pun yang lebih dari 576 byte dapat dibagi, paket yang di bawah ukuran itu mungkin tidak; embedded system yang tidak dapat menangani paket split harus menghindari meminta sesuatu yang lebih besar dari itu.
supercat
1
@ mauro.stettler: Saya telah menulis tumpukan TCP pada "bare metal" (menulis kode untuk berbicara langsung ke sejumlah chip antarmuka jaringan). Untuk perangkat keras yang berbicara ke tautan dengan batas 576 byte untuk membagi paket yang lebih lama adalah hal yang sederhana. Merakit kembali paket jauh lebih rumit, terutama karena seseorang dapat menerima potongan paket yang berbeda sebelum salah satu dari mereka diterima secara penuh.
supercat
Ada beberapa harapan bahwa itu tidak akan dibagi untuk muatan kecil (sekitar 10 atau 20 byte harus ok), karena ada "ukuran maksimum dijamin" yang diperlukan dari setiap hop untuk paquets IP pada ipv4: setidaknya 68 byte (termasuk Header IP, dan tidak termasuk header level bawah). lihat tabel 1 di en.wikipedia.org/wiki/Maximum_transmission_unit . Berbeda dari 576 byte ukuran minimal yang diperlukan dari HOSTS (yaitu, asal atau akhir transmisi, tidak semua hop perantara). Dan hati-hati: payload masih lebih rendah (karena header setiap lapisan mengambil ruang).
Olivier Dulac
14

Contohnya. Blok karakter yang berdekatan sesuai dengan pengiriman () panggilan:

TCP:

Send: AA BBBB CCC DDDDDD E         Recv: A ABB B BCC CDDD DDDE

Semua data yang dikirim diterima secara berurutan, tetapi tidak harus dalam potongan yang sama.

UDP:

Send: AA BBBB CCC DDDDDD E         Recv: CCC AA E

Data tidak harus dalam urutan yang sama, dan tidak harus diterima sama sekali, tetapi pesan dipertahankan secara keseluruhan.

Jim Cote
sumber
5

Misalnya: jika saya mengirim 20 byte menggunakan protokol TCP, dapatkah saya 100% yakin bahwa saya akan menerima tepat 20 byte sekaligus, bukan 10 byte kemudian 10 byte lagi atau lebih?

Tidak, TCP adalah protokol streaming, ini menyimpan data dalam urutan tetapi tidak mengelompokkannya melalui pesan. Di sisi lain UDP berorientasi pada pesan, tetapi tidak dapat diandalkan. SCTP memiliki yang terbaik dari kedua dunia tetapi tidak dapat digunakan secara alami karena NAT menghancurkan Internet.

Changaco
sumber
1

Ada beberapa jaminan bahwa jika Anda mengirim 20 byte di awal aliran TCP, itu tidak akan tiba sebagai dua buah 10 byte. Ini karena TCP stack tidak akan mengirim segmen sekecil itu: ada ukuran MTU minimum. Namun, jika pengiriman ada di mana saja di tengah aliran, semua taruhan dibatalkan. Bisa jadi stack protokol Anda membutuhkan 10 byte data untuk mengisi segmen dan mengirimkannya, dan kemudian sepuluh byte berikutnya pergi ke segmen lain.

Tumpukan protokol Anda memecah data menjadi potongan-potongan dan menempatkannya ke dalam antrian. Ukuran chunk didasarkan pada jalur MTU. Jika Anda melakukan operasi pengiriman, dan masih ada data yang antri menunggu, tumpukan protokol biasanya akan mengintip segmen yang berada di ujung antrian dan melihat apakah ada ruang di segmen itu untuk menambahkan lebih banyak data. Ruangan bisa sekecil satu byte, sehingga bahkan pengiriman dua byte dapat dipecah menjadi dua.

Di sisi lain, segmentasi data berarti bahwa mungkin ada pembacaan parsial. Operasi penerimaan berpotensi bangun dan mendapatkan data ketika sedikitnya satu segmen tiba. Dalam API soket yang diterapkan secara luas, panggilan terima dapat meminta 20 byte, tetapi bisa kembali dengan 10. Tentu saja, lapisan penyangga dapat dibangun di atasnya yang akan memblokir hingga 20 byte diterima, atau koneksi terputus. Di dunia POSIX, API itu bisa menjadi stream I / O standar: Anda bisa fdopendeskriptor socket untuk memperoleh FILE *stream, dan Anda bisa menggunakannya freaduntuk mengisi buffer sehingga permintaan penuh dipenuhi dengan sebanyak mungkin readpanggilan yang diperlukan .

Datagram UDP membingkai data. Setiap panggilan kirim menghasilkan datagram (tetapi lihat di bawah tentang penyumbatan). Sisi lain menerima datagram lengkap (dan, di API soket, ia harus menentukan buffer yang cukup besar untuk menahannya, atau datagram akan terpotong). Datagram besar terfragmentasi oleh fragmentasi IP, dan dirakit ulang secara transparan ke aplikasi. Jika ada fragmen yang hilang, seluruh datagram hilang; tidak ada cara untuk membaca sebagian data dalam situasi itu.

Ada ekstensi ke antarmuka yang memungkinkan beberapa operasi menentukan datagram tunggal. Di Linux, soket dapat "disumbat" (dicegah mengirim). Sementara itu disumbat, data tertulis dikumpulkan menjadi satu unit. Kemudian ketika soket "terbuka", satu datagram dapat dikirim.

Kaz
sumber
ini salah: jika seseorang mengirim paquet dengan muatan 10 atau 20 byte, ini akan menghasilkan 1 paquet, dan (seperti yang saya katakan di atas), jika menggunakan ipv4, seharusnya, bahkan ketika menambahkan semua header dari lapisan protokol lainnya, pas ke dalam 68 byte, sehingga memastikan bahwa ia melewati semua hop dalam 1 paket. Tcp stack tidak akan (seperti yang ditunjukkan pada paragraf 1 Anda) "tunggu sampai mtu terisi (yaitu, tambahkan beberapa paket untuk membuat yang berukuran tepat)" untuk mengirim paket! ... Karena ini akan merusak banyak hal ( bahkan jika "fragmen" itu dikirim dari & ke pasangan host yang sama)
Olivier Dulac
@OlivierDulac: Itu tidak benar. TCP biasanya menghasilkan paket sesuai kebutuhan, mencoba mengoptimalkan penggunaan jaringan, sehingga 20 byte dapat berakhir dalam dua paket yang berbeda seperti yang dijelaskan oleh Kaz. Ini dapat dikontrol menggunakan opsi soket TCP_NODELAY , yang menonaktifkan algoritma Nagles yang mengirimkan byte ke paket, jika aplikasi Anda membutuhkan jaringan TCP yang lebih cepat. Juga, 68 byte sama sekali bukan standar de-facto untuk panjang paket: 1500 byte adalah nilai default yang lebih biasa (ini benar-benar bervariasi antar jaringan).
jjmontes