9.10. TCP -- aliran byte yang andal

TCP, Transmission Control Protocol, adalah layanan lapisan transport lainnya di atas IP. Jika UDP paling tepat digambarkan sebagai "kirim paket dan harap yang terbaik", maka TCP adalah "buka koneksi antara dua titik ujung dan perlakukan sebagai pipa dua arah berisi byte yang pasti diterima oleh pihak lain, secara berurutan, dan tepat sekali". Sebagian besar lalu lintas internet menggunakannya, dan sebagian besar yang dilakukan kamera di jaringan juga menggunakannya.

9.10.1. Apa yang TCP tambahkan ke IP

TCP melakukan jauh lebih banyak daripada UDP. TCP menambahkan:

  • Sebuah koneksi. Sebelum data mengalir, kedua titik ujung bertukar jabat tangan singkat untuk menyetujui bahwa mereka sedang berkomunikasi. Koneksi memiliki status -- "terbuka", "setengah tertutup", "tertutup" -- yang dipantau oleh kedua sisi.

  • Pengiriman yang andal. Setiap byte yang dimasukkan pengirim diakui oleh penerima. Apa pun yang tidak diakui dalam batas waktu tertentu akan dikirim ulang. Aplikasi tidak pernah melihat byte yang hilang; yang terlihat adalah penundaan saat protokol mengirim ulang.

  • Pengiriman berurutan. Byte tiba dalam urutan yang sama seperti saat dikirim. Bahkan jika paket tiba di penerima dalam urutan yang salah, TCP menyusunnya kembali sebelum aplikasi membaca.

  • Kontrol aliran. Jika penerima lambat, pengirim diberitahu untuk melambat; koneksi menyesuaikan dengan kecepatan sisi yang lebih lambat.

  • Kontrol kemacetan. Jika jaringan di tengah mulai menjatuhkan paket, pengirim mundur hingga keadaan membaik. Ini mencegah satu koneksi mana pun merusak tautan yang sudah jenuh.

Semua ini berjalan otomatis. Python API yang digunakan aplikasi hanyalah send(bytes) dan recv(n); TCP menangani segalanya di bawah.

9.10.2. Jabat tangan

Koneksi TCP dibuka dengan pertukaran tiga arah sebelum data apa pun diizinkan lewat:

A diagram with two columns labelled "client" and "server". An arrow from client to server labelled "SYN", then an arrow from server to client labelled "SYN-ACK", then an arrow from client to server labelled "ACK". Below that a thick arrow labelled "data flowing both ways".

Jabat tangan tiga arah. Setelah kedua sisi saling mengakui, koneksi terbuka dan data dapat mengalir.

Client mengirim paket SYN (synchronise) untuk meminta pembukaan. Server membalas dengan SYN-ACK (synchronise + acknowledge), menerima permintaan. Client mengirim ACK terakhir untuk konfirmasi. Setelah putaran perjalanan ini, kedua sisi menyetujui bahwa koneksi terbuka dan telah menyinkronkan penghitung mereka untuk melacak byte mana yang telah dikirim dan diterima.

Jabat tangan dikenakan biaya latensi satu kali perjalanan pulang-pergi sebelum byte pertama yang berguna diterima. Untuk jaringan lokal, ini hanya satu milidetik; untuk koneksi lintas benua, ini sekitar 100 ms. Inilah biaya utama TCP dan alasan mengapa pesan singkat sekali jalan terkadang lebih baik menggunakan UDP.

9.10.2.1. Jabat tangan penutupan

Koneksi TCP juga ditutup dengan pertukaran (sebuah FIN dari masing-masing sisi). Salah satu ujung dapat menutup separuh koneksinya secara independen; status setengah tertutup di mana satu sisi telah selesai mengirim namun sisi lain masih berkomunikasi adalah sah, meskipun jarang terjadi. Aplikasi biasanya cukup memanggil close() dan membiarkan protokol menangani urutan penutupan.

9.10.3. Apa yang TCP tidak jamin

Beberapa hal yang kadang diasumsikan dilakukan TCP tetapi sebenarnya tidak:

  • Batas pesan. Aplikasi mengirim aliran byte, bukan aliran pesan. Dua panggilan send(b"hello") mungkin tiba sebagai satu recv() dari b"hellohello", atau sebagai dua recv()s dengan ukuran yang bervariasi. Jika aplikasi menginginkan pembingkaian pesan, ia harus menambahkan pembingkaian sendiri (baris baru, awalan panjang, atau apa pun). Mengirim dokumen JSON melalui TCP, misalnya, memerlukan setiap dokumen dipisahkan oleh baris baru atau penanda lainnya.

  • Enkripsi. TCP membawa byte yang diberikan aplikasi, secara jelas, sampai tujuan. Jika kontennya perlu bersifat rahasia, aplikasi harus membungkus koneksi dalam TLS (lihat Socket terenkripsi dan TLS).

  • Autentikasi. TCP memastikan byte tiba secara utuh. Ia tidak mengatakan apa pun tentang siapa yang mengirimnya. Autentikasi juga merupakan urusan lapisan yang lebih tinggi.

  • Keaktifan pada koneksi yang sepi. Jika tidak ada sisi yang mengirim data dalam waktu lama, koneksi secara teknis masih terbuka tetapi tidak dapat mendeteksi bahwa ujung lain telah crash atau menghilang. Probe Keepalive dapat diaktifkan pada socket untuk memperbaiki ini bila diperlukan.

9.10.4. Kapan menggunakan TCP

TCP adalah jawaban yang tepat untuk hampir semua percakapan yang memiliki bentuk "client membuka koneksi ke server, mereka bertukar beberapa byte, koneksi ditutup setelah selesai". Permintaan HTTP dan HTTPS, sesi SSH, kueri database, transfer file, unggah citra -- semuanya melalui TCP.

Pilih UDP hanya ketika percakapan tidak sesuai dengan bentuk itu: pesan independen yang berdiri sendiri di mana kehilangan dapat diterima, lalu lintas multicast, sinkronisasi waktu, pencarian nama, atau kasus dengan latensi ekstrem di mana biaya jabat tangan sangat tinggi.

Dengan port, UDP, dan TCP semuanya tersedia, kisah lapisan transport selesai. Python API yang mengekspos keduanya ada di halaman berikutnya: Objek socket.