Solusi untuk penemuan rekan LAN yang ringan?

9

Saya membangun perpustakaan untuk pemrograman lintas platform murni. Game saya dibuat dengan berjalan baik di Android, Pc, Linux, Mac dll.

Kemampuan jaringan disediakan oleh pustaka ENET, oleh karena itu semua komunikasi antara aplikasi saya tidak kompatibel dengan TCP atau UDP, tetapi hanya dalam protokol khusus, bahkan yang paling sulit didasarkan pada UDP pada akhirnya.

Saya pikir tidak mungkin untuk melakukan apa yang saya inginkan dengan ENET, itu sebabnya saya meminta bantuan di sini!

Katakanlah saya memiliki permainan yang sama berjalan di ponsel Android saya, laptop saya dan pc saya. Mereka semua berada di jaringan wifi yang sama, dan karenanya di LAN, apakah hotspot Wifi (?) Atau router rumah tangga.

Saya membutuhkan masing-masing dari 3 rekan untuk menemukan dua lainnya di jaringan. Ini dimaksudkan hanya untuk menemukan IP aplikasi yang hidup di jaringan LAN, untuk dapat meng-host game multipemain di antara mereka.

Saya hanya bisa memikirkan satu cara efektif untuk melakukan ini, siaran UDP, menunggu tanggapan, tetapi jika itu solusinya, saya perlu sesuatu yang kecil, karena itu satu-satunya tujuan implementasi.

Cara lain bisa dengan mencoba menghubungkan ke semua IP di subrange alamat LAN, tapi saya tidak berpikir OS akan dengan saya yang satu ini: p

Grimshaw
sumber
2
Saya pikir beberapa siaran UDP adalah jalan yang harus ditempuh, dan saya tidak mengerti keberatan Anda terhadapnya, atau apakah ENET tidak mendukung siaran?
Roy T.
Tepat, tidak, itu hanya dapat disiarkan ke teman-teman yang sudah dikenal ..
Grimshaw
stackoverflow.com/questions/683624/... Apakah ini memengaruhi jawaban?
Grimshaw

Jawaban:

5

Seperti yang telah dikatakan banyak orang, solusinya adalah menggunakan siaran UDP , tetapi ada banyak detail implementasi yang terlibat. Saya baru-baru ini mengalami masalah yang sama, dan setelah mencari solusi saya membuat posting blog , dan proyek sampel dalam bentuk server obrolan LAN / klien. Saya akan meringkasnya di sini, tetapi Anda harus memeriksanya untuk lebih jelasnya, dan kode nyata.

Begini cara kerjanya, berdasarkan pada deskripsi oleh Lee Salzman, pencipta ENet:

  • Server game Anda berjalan pada satu soket, sebagai host ENet
  • Server juga mengikat ke port "mendengarkan" yang dikenal, sebagai soket UDP biasa (yaitu bukan host ENet)
  • Klien mengirim pesan siaran UDP (mis. IP 255.255.255.255) ke port pendengar itu, dan menunggu tanggapan
  • Semua server di LAN akan menerima pesan "pemindaian" itu, dan merespons. Idealnya, Anda dapat merespons dengan port tempat server game (host ENet) dijalankan; dengan cara itu Anda tidak harus memiliki server gim Anda berjalan pada port tetap)
  • Setelah klien menerima beberapa tanggapan, ia akan tahu server mana yang hadir. Kemudian Anda dapat memilih salah satu dari mereka untuk terhubung, sebagai rekan ENet biasa. Pada titik ini klien tidak perlu lagi soket "pemindai" UDP.

Berita baiknya adalah ENet menyediakan fungsi pembungkus untuk menggunakan soket , sehingga Anda dapat melakukan semuanya di ENet. Berita buruknya adalah bungkusnya sangat tipis; Anda harus tahu tentang pemrograman soket , seperti apa select()fungsinya. Inilah sebabnya saya mendorong Anda untuk melihat posting blog dan proyek sampel sehingga Anda dapat menyalin / menempelkan kode dan menghemat banyak waktu bagi diri Anda sendiri.

Berikut adalah beberapa catatan dan perangkap yang harus Anda pilih untuk melakukan implementasi Anda sendiri:

  • Pendengar / pemindai haruslah UDP, jadi Anda harus membuatnya menggunakan enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM)(atau SOCK_DGRAMuntuk pemrograman soket lama biasa)
  • Untuk "pendengar" server, izinkan alamat port untuk digunakan kembali menggunakan enet_socket_set_option(socket, ENET_SOCKOPT_REUSEADDR, 1)(atau SO_REUSEADDR) sehingga beberapa server dapat berjalan pada IP yang sama
  • Untuk "pemindai" klien, Anda harus mengaktifkan siaran pada soket UDP menggunakan enet_socket_set_option(scanner, ENET_SOCKOPT_BROADCAST, 1)(atau SO_BROADCAST), jika tidak, Anda tidak dapat mengirim ke alamat siaran. Ini adalah fitur keselamatan saja , untuk mempersulit membanjiri jaringan secara tidak sengaja.

Sayangnya ini bukan solusi yang "ringan"; proyek sampel jam di beberapa ratus LOC sama sekali. Akan lebih baik jika ini dikemas ke pustaka utilitas untuk ENet, tetapi saya telah menemukan bahwa untuk server game, Anda sering ingin mengirim beberapa informasi lebih spesifik game dengan balasan server untuk menjadikan ini berguna, seperti:

  • Jenis permainan (mis. "Co-op", "deathmatch")
  • "Peta", "level" atau "kampanye" yang dijalankan server
  • Jumlah pemain dan pemain maksimal untuk server
  • Informasi spesifik game apa pun yang akan memengaruhi keputusan klien untuk terhubung atau tidak. Pikirkan tentang "browser server" dalam game dan jenis informasi yang ditampilkan.
congusbongus
sumber
Inilah yang saya pikirkan. Penyiaran adalah cara untuk pergi.
Lolums
3

Ketika Anda tidak ingin meninggalkan perpustakaan Anda, Anda bisa menggunakan brute-force dan mencoba untuk terhubung ke masing-masing alamat yang mungkin. Kebanyakan home lans adalah jaringan Class-C (/ 24) di mana 24 bit pertama dari alamat IP adalah sama dan 8 bit terakhir berbeda. Jadi, Anda hanya memiliki 255 kemungkinan alamat IP.

Tapi tetap saja, melakukan siaran UDP akan menjadi alternatif yang lebih bersih. Kirimkan saja paket UDP ke 255.255.255.255 dan semua klien di belakang router yang sama akan menerimanya. Mereka kemudian dapat mengirim balasan ke IP sumber dan port sumber paket untuk memberi tahu pengirim bahwa mereka hadir.

Philipp
sumber
2
Tolong tolong tolong tolong jangan kasar!
Trevor Powell
@ TrevorPowell ... karena ...?
Philipp
2
Karena itu solusi yang salah. Ini tidak akan berfungsi di universitas (yang tidak menggunakan jaringan class-c) atau di bisnis (yang juga biasanya tidak menggunakan jaringan class-c), dan staf TI akan sangat tidak menyukai beban yang disebabkan oleh setiap pemain yang membuat brute-force mencoba mengirim pesan ke setiap alamat IP di jaringan mereka setiap kali mereka mengklik tombol 'refresh'. Itu hanya solusi buruk untuk masalah ini . Pertanyaan tentang mencari teman sebaya yang potensial tanpa server pembuat matematika ini tepat untuk siaran apa. Gunakan siaran. Lebih baik dalam segala hal. :)
Trevor Powell
1

Anda bisa melihatnya di DNS-SD / ZeroConf / Avahi / Bonjour / mDNS . Ini adalah hal yang Apple gunakan untuk berbagi printer, folder iTunes dan sebagainya, tetapi sudah diadopsi di tempat lain. Avahi adalah versi opensource yang digunakan Linux (tidak yakin apakah itu Linux), tidak yakin seberapa portabel semuanya (walaupun ada implementasi untuk sebagian besar platform).

Setelah mengatakan semua itu, mungkin lebih mudah untuk melakukan siaran UDP.

David C. Bishop
sumber