12.5. Keandalan -- urutan, ACK, transmisi ulang¶
Lapisan framing mendeteksi kerusakan dengan CRC-nya. Lapisan keandalan mengubah "kerusakan yang terdeteksi" menjadi "aplikasi tidak pernah melihat data yang rusak" dengan menegosiasikan transmisi ulang setiap kali sebuah paket tidak tiba dalam kondisi utuh.
12.5.1. Nomor urutan¶
Setiap header paket membawa satu byte nomor urutan, terpisah untuk setiap arah perjalanan. Pengirim menaikkan counter sebelum transmisi; penerima memeriksa bahwa urutan setiap paket yang diterima adalah urutan sebelumnya ditambah satu (modulo 256).
Tiga hal dapat muncul di penerima selain paket yang bersih dan berurutan:
Nomor urutan yang diharapkan, dengan CRC yang valid. Paket dikirim ke lapisan berikutnya.
Nomor urutan yang diharapkan, dengan CRC yang buruk. Penerima membuang paket dan (jika ACK dinegosiasikan) mengirimkan NAK meminta transmisi ulang.
Nomor urutan yang satu lebih tinggi dari yang diharapkan, dengan CRC yang valid. Penerima mengetahui paket sebelumnya hilang; ia mengirimkan NAK yang merujuk pada urutan yang terlewat dan menyimpan yang baru.
Kasus duplikat (transmisi ulang yang tiba setelah yang asli akhirnya berhasil melewati) ditangani dengan memeriksa terhadap counter yang diharapkan: jika urutannya di belakang yang diharapkan, paket adalah duplikat dan penerima membuangnya setelah mengirimkan ACK yang jelas tidak diterima pengirim pertama kali.
12.5.2. ACK dan NAK¶
Dua bit flag dalam header paket membawa lalu lintas keandalan itu sendiri:
ACK_REQyang disetel pada paket keluar berarti "Saya ingin konfirmasi kembali." Paket data biasanya menyetel ini; ping status dan acara satu kali mungkin tidak.ACKyang disetel pada paket berarti "paket ini adalah konfirmasi untuk nomor urutan dalam header." Ia tidak membawa payload sendiri.NAKyang disetel berarti "paket ini menolak yang sebelumnya" -- biasanya karena CRC yang buruk atau celah nomor urutan. Header mengarahkan pengirim pada urutan mana yang harus ditransmisikan ulang.
Pengirim menjalankan loop stop-and-wait: ia mengirimkan satu paket yang memerlukan konfirmasi, kemudian menunggu ACK (atau NAK) yang sesuai sebelum mengirim yang berikutnya. Model single-in-flight menjaga keadaan pengirim tetap terbatas -- beberapa ratus byte pada cam terkecil -- dan sesuai dengan peran protokol sebagai saluran kontrol antara dua endpoint daripada pipa yang dioptimalkan throughput. Pada NAK pengirim mentransmisikan ulang paket yang sama dengan flag RTX disetel sehingga penerima tahu ini adalah percobaan ulang.
12.5.3. Waktu transmisi ulang¶
Jika ACK maupun NAK tidak tiba dalam batas waktu transmisi ulang, pengirim mentransmisikan ulang paket in-flight sendiri. Batas waktu default ke 500 ms dan berlipat ganda pada setiap percobaan ulang berturut-turut (1 s, 2 s, ...). Setelah jumlah percobaan ulang yang dikonfigurasi -- default tiga -- pengirim menyerah dan melaporkan kesalahan transport ke aplikasi.
Penggandaan batas waktu adalah pola exponential backoff standar. Batas waktu pertama yang singkat menangkap paket yang hilang dengan cepat; penggandaan berarti host yang sibuk selama beberapa ratus milidetik tidak memicu badai duplikat yang memperparah beban.
12.5.4. Mengonfigurasi keandalan¶
Kedua ujung dapat mematikan bagian dari lapisan keandalan, atas persetujuan, ketika aplikasi dapat menanggung kehilangan data:
protocol.init(ack=False)menonaktifkan ACK per paket. Pengirim menembak dan melupakan; penerima menyampaikan apa pun yang tiba. Baik untuk data sensor streaming di mana sampel yang kedaluwarsa dapat diterima.protocol.init(seq=False)mematikan pelacakan nomor urutan, yang menyiratkan ACK juga dimatikan. Berguna hanya pada transport yang benar-benar andal.protocol.init(crc=False)mematikan validasi CRC tetapi membiarkan sisa framing tetap utuh. Layak dilakukan hanya ketika transport itu sendiri cukup kuat sehingga kesalahan CRC tidak terjadi.
Default -- semuanya aktif -- adalah titik awal yang tepat untuk sesi debugging host-ke-cam apa pun. Setelah aplikasi dalam produksi, trade-off menjadi spesifik pada datanya dan transportnya.
12.5.5. Kode status¶
Ketika kesalahan transport memang merambat ke kode aplikasi, ia tiba sebagai kode status. Pustaka protokol mendefinisikan sepuluh:
SUCCESS-- operasi selesai.FAILED-- perintah gagal karena alasan yang tidak ditentukan.INVALID-- penerima menolak perintah atau salah satu argumennya.TIMEOUT-- timer percobaan ulang habis.BUSY-- cam sedang sibuk (biasanya saluran yang terkunci).CHECKSUM-- CRC header atau payload tidak cocok.SEQUENCE-- nomor urutan di luar urutan melampaui kemampuan pemulihan lapisan.OVERFLOW-- payload melebihi maksimum yang dinegosiasikan.FRAGMENT-- pesan multi-fragmen tiba dengan bagian yang hilang.UNKNOWN-- penangkapan defensif untuk kondisi yang benar-benar tidak terduga.
Kode host yang memanggil channel_read() melihat ini sebagai pengecualian Python; kode aplikasi sisi cam yang telah memilih penanganan kesalahan kustom melihatnya sebagai nilai kembalian dari callback backend. Sebagian besar aplikasi cam tidak perlu melihat kode status sama sekali -- pustaka menangani percobaan ulang, dan hanya kegagalan yang benar-benar tidak dapat dipulihkan (misalnya transport itu sendiri hilang) yang mencapai aplikasi.
Dengan framing yang ada untuk mendeteksi kerusakan dan keandalan yang ada untuk memulihkannya, pekerjaan tingkat kabel selesai. Kode aplikasi melihat paket yang dibingkai, berurutan, dan utuh; byte di dalamnya bebas berarti apa pun yang diinginkan saluran di atasnya.