Saya punya pertanyaan tentang UDP. Untuk konteks, saya sedang mengerjakan game aksi real-time.
Saya sudah membaca sedikit tentang perbedaan antara UDP dan TCP dan saya merasa saya memahaminya dengan baik, tetapi ada satu bagian yang tidak pernah terasa benar, dan itu keandalan , dan secara khusus ucapan terima kasih . Saya mengerti bahwa UDP tidak menawarkan keandalan secara default (yaitu paket dapat dibatalkan atau tiba tidak sesuai pesanan). Ketika beberapa keandalan diperlukan, solusi yang saya lihat (yang masuk akal secara konseptual) adalah dengan menggunakan ucapan terima kasih (yaitu server mengirim paket ke klien, dan ketika klien menerima pesan itu, ia mengirim kembali pengakuan ke server) .
Apa yang terjadi ketika pengakuan dijatuhkan?
Dalam contoh di atas (satu server mengirim paket ke satu klien), server menangani kemungkinan kehilangan paket dengan mengirim kembali paket setiap frame sampai ucapan terima kasih diterima untuk paket-paket itu. Anda masih bisa mengalami masalah bandwidth atau pesan out-of-order, tetapi murni dari perspektif packet-loss, server dicakup.
Namun, jika klien mengirim pemberitahuan yang tidak pernah tiba, server tidak akan punya pilihan selain berhenti mengirim pesan itu, yang dapat merusak permainan jika informasi yang terkandung dalam paket itu diperlukan. Anda dapat mengambil pendekatan yang mirip dengan server (yaitu terus mengirim ucapan terima kasih hingga Anda menerima ack untuk ack?), Tetapi pendekatan itu akan membuat Anda berulang kali bolak-balik (karena Anda memerlukan ack untuk ack untuk ack untuk ack? dan seterusnya).
Saya merasa logika dasar saya benar di sini, yang membuat saya memiliki dua opsi.
- Kirim paket pengakuan tunggal dan berharap yang terbaik.
- Kirim beberapa paket ucapan terima kasih (mungkin 3-4) dan berharap yang terbaik, dengan asumsi bahwa tidak semuanya akan dijatuhkan.
Apakah ada jawaban untuk masalah ini? Apakah saya salah paham secara mendasar tentang sesuatu? Apakah ada jaminan menggunakan UDP yang tidak saya sadari? Saya merasa ragu untuk bergerak maju dengan terlalu banyak kode jaringan sampai saya merasa nyaman karena logika saya sehat.
sumber
Jawaban:
Ini adalah bentuk Masalah Dua Jenderal , dan Anda benar - tidak ada jumlah percobaan yang cukup untuk menjamin penerimaan dengan sempurna.
Dalam latihan di gim, biasanya ada cakrawala waktu di mana informasi tidak terlalu penting walaupun itu secara teknis dapat diandalkan. Seperti mengetahui bahwa Anda memiliki headshot yang sempurna berbaris 2 detik yang lalu - sudah terlambat bagi pemain untuk menggunakan informasi itu sekarang.
Jika kehilangan paket Anda sangat tinggi sehingga Anda tidak dapat secara rutin mendapatkan info yang dibutuhkan melalui jendela reaksi ketat, maka untuk permainan waktu nyata Anda mungkin lebih baik menendang pemain dan mencoba menemukan kecocokan yang lebih baik untuk mereka di tempat lain, daripada terus mencoba mengirim paket untuk meniru koneksi yang andal.
Karena itu, beberapa sistem replikasi game melewatkan pengakuan & mencoba ulang sama sekali dan memilih hanya mengirim spam pembaruan terbaru sesering mungkin. Jika seseorang terjatuh atau datang terlambat, sayang sekali, lewati saja, ambil yang berikutnya dan lanjutkan, mengandalkan sistem prediksi & interpolasi untuk memperlancar jarak dan meminimalkan cegukan yang terlihat oleh pemain.
Saya tiba-tiba ingin mulai menyebut ini "Replikasi Simba" untuk bagaimana ia mengabaikan masalah di masa lalu dan mencoba untuk hidup di saat ini. ;)
Solusi hibrida adalah berlomba untuk mengirimkan pembaruan baru DAN (karena pembaruan keadaan permainan sering kali sangat kecil / kompresibel) ) juga mengemas pembaruan terakhir, dan mungkin yang sebelum itu ... Jadi kalau-kalau klien melewatkannya , Anda tidak perlu menunggu waktu perjalanan penuh untuk mencari tahu dan memperbaikinya. Sebagian besar waktu klien sudah melihat ini, jadi ada data yang berlebihan dengan cara ini, tetapi latensi untuk memperbaiki pesan yang terlewatkan lebih rendah. Pembaruan klien dapat menyertakan nomor indeks dari pembaruan berturut-turut terbaru yang pernah mereka lihat, sehingga Anda dapat sedikit konservatif dengan berapa banyak pembaruan lama yang Anda sertakan dalam paket pembaruan berikutnya.
Anda juga dapat menerapkan sistem dua tingkat sebagai jenis hibrid lain, di mana keadaan berumur pendek direplikasi dengan cara cepat-api yang tidak dapat diandalkan, dan keadaan jangka panjang disinkronkan secara andal, menggunakan TCP atau implementasi keandalan Anda sendiri dengan coba lagi menghitung. Ini menjadi lebih rumit untuk dikelola, karena Anda memiliki dua sistem pengiriman pesan untuk dipelihara, dan kedua snapshot tersebut dapat tidak selaras satu sama lain, menambahkan kelas kasus tepi yang sama sekali baru.
sumber
Pendekatan yang digunakan TCP adalah pengirim akan terus mengirim ulang paket sampai menerima pemberitahuan. Penerima akan mengabaikan paket duplikat, tetapi masih mengirimkan ucapan terima kasih kepada mereka. Pengirim akan mengabaikan duplikat ucapan terima kasih.
Jika suatu paket hilang, pengirim mengirimnya kembali, seperti yang sudah Anda ketahui.
Jika pemberitahuan hilang, pengirim mengirim ulang paket aslinya, yang menyebabkan penerima mengirim ulang pemberitahuan.
Jika pengakuan tidak diterima dalam waktu tertentu (mungkin 60 detik, atau 20 coba lagi) maka pemain dianggap terputus dari permainan. Anda harus menerapkan semacam aturan batas waktu, atau jika pemain yang mencabut kabel jaringannya akan mengikat sumber daya di server Anda selamanya.
sumber
Jika Anda ingin menemukan kembali TCP, masuk akal untuk melihat TCP terlebih dahulu, yang berkaitan dengan masalah yang Anda jelaskan (bagian dari solusi adalah menggunakan nilai yang ditentukan pengguna untuk mencoba ulang dan waktu habis).
Solusi yang menggunakan 2 saluran, saluran TCP (untuk komunikasi yang andal) serta saluran UDP (untuk komunikasi latensi rendah) tidak jarang.
Beberapa solusi mendeteksi ketika klien melewatkan beberapa informasi terlalu lama, dan memulai sinkronisasi ulang, yang mungkin menggunakan UDP atau TCP.
Pendekatan umum lainnya adalah merancang komunikasi sedemikian rupa sehingga tidak mengandalkan pengakuan sama sekali, tetapi itu di luar ruang lingkup pertanyaan.
sumber
Dalam RTS Anda benar-benar tidak dapat menggunakan protokol seperti TCP, dan Anda juga tidak bisa membuat UDP dapat diandalkan. Jika Anda mencoba, permainan akan membeku setiap kali ada hick-up jaringan.
Sebagai gantinya, Anda mendesain protokol sehingga paket yang terlewatkan tidak terlalu penting.
Versi singkatnya adalah Anda tidak peduli di mana para pemain lainnya berada di frame terakhir selama Anda tahu di mana mereka sekarang . Versi panjang lebih rumit.
Pertanyaannya kemudian, apa yang Anda lakukan ketika sebuah paket hilang? Dan jawabannya adalah ... Anda menebak. Pemain mungkin bergerak dalam garis lurus, bukan? Pindahkan mereka satu langkah lebih jauh di sepanjang garis itu. ... Kecuali tidak ada pemain RTS yang pernah bergerak dalam garis lurus. Dan kemudian ada deteksi tabrakan.
Ini sulit. Banyak game yang salah. Dapat dikatakan bahwa tidak ada jawaban yang tepat untuk ini, hanya berbagai kesalahan yang dapat ditukar.
Alasan mengapa game-game ini bekerja dengan baik bukan hanya karena mereka telah berpikir panjang dan keras tentang masalah-masalah ini, tetapi juga bahwa Internet telah menjadi sangat andal. Hampir semua paket UDP benar-benar mencapai tujuan mereka tepat waktu. (Kecuali jika ada masalah permanen seperti firewall)
sumber