Hafif LAN eş keşfi için çözüm mü?


9

Tamamen çapraz platform programlaması için bir kütüphane kurdum. Onunla yapılan oyunlarım Android, Pc, Linux, Mac vb.

Ağ oluşturma yetenekleri ENET kitaplığı tarafından sağlanır, bu nedenle uygulamalarım arasındaki tüm iletişim TCP veya UDP uyumlu değildir, ancak yalnızca özel protokolde bulunur, hatta sonuç olarak UDP'ye dayanır.

ENET ile istediğimi yapmanın mümkün olduğunu düşünmüyorum, bu yüzden burada yardım istiyorum!

Diyelim ki aynı oyun Android telefonumda, dizüstü bilgisayarımda ve bilgisayarımda çalışıyor. Hepsi aynı wifi ağında ve bu nedenle bir WiFi'de, Wifi hotspot (?) Veya ev yönlendiricisi olsun.

Ağdaki diğer ikisini keşfetmek için bu 3 eşin her birine ihtiyacım var. Bu, yalnızca LAN ağındaki canlı uygulamaların IP'sini bulmak, aralarında çok oyunculu oyunları barındırabilmektir.

Bunu yapmak için sadece bir etkili yol düşünebilirim, UDP yayını, cevapları beklemek, ancak çözüm ise, küçük bir şeye ihtiyacım var, çünkü uygulamanın tek amacı bu.

Diğer yol LAN adresi alt aralıktaki tüm IP'lere bağlanmaya çalışmak olabilir, ancak işletim sisteminin bu konuda benimle olacağını düşünmüyorum: p


2
Sanırım birkaç UDP yayını gidilebilecek bir yol ve itirazlarınızı anlamıyorum ya da ENET'in yayınları desteklememesi mi?
Roy T.

Kesinlikle, öyle değil, sadece zaten bilinen akranlarına yayın yapabilir ..
Grimshaw

Yanıtlar:


5

Birçok kişinin söylediği gibi, çözüm UDP yayınını kullanmak olacaktır , ancak birçok uygulama detayı söz konusudur. Geçenlerde aynı sorunla karşılaştım ve bir çözüm üzerinde çalıştıktan sonra bir blog yazısı ve LAN sohbet sunucusu / istemcisi şeklinde örnek bir proje yaptım . Bunları burada özetleyeceğim, ancak daha fazla ayrıntı ve gerçek kod için onları kontrol etmelisiniz.

ENet'in yaratıcısı Lee Salzman'ın açıklamasına dayanarak şöyle çalışır :

  • Oyun sunucunuz bir ENet ana bilgisayarı olarak tek bir yuvada çalışır
  • Sunucu ayrıca bilinen bir "dinleme" bağlantı noktasına, normal bir UDP soketi olarak bağlanır (yani bir ENet ana bilgisayarı değil)
  • İstemci, bu dinleme bağlantı noktasına bir UDP yayın iletisi (yani IP 255.255.255.255) gönderir ve yanıt bekler
  • LAN'daki tüm sunucular bu "tarama" iletisini alır ve yanıt verir. İdeal olarak oyun sunucusunun (ENet host) çalıştığı port ile cevap verebilirsiniz; böylece oyun sunucunuzun sabit bir bağlantı noktasında çalışmasına gerek kalmaz)
  • İstemci bazı yanıtlar aldıktan sonra, hangi sunucuların bulunduğunu bilecektir. Ardından, normal bir ENet eşi olarak bağlanmak için bunlardan birini seçebilirsiniz. Bu noktada istemcinin artık UDP "tarayıcı" soketine ihtiyacı yoktur.

İyi haber şu ki ENet, soketleri kullanmak için sarıcı fonksiyonlar sağlıyor , böylece ENet'te her şeyi yapabilirsiniz. Kötü haber, sargının son derece incedir; ne gibi soket programlama hakkında bilmeniz gerekir select(). Bu nedenle , kodu kopyalayıp yapıştırabilmeniz ve kendinize çok zaman kazandırabilmeniz için blog yayınına ve örnek projeye göz atmanızı öneririm.

Kendi uygulamanızı yapmayı seçmeniz gereken bazı notlar ve tuzaklar:

  • Dinleyici / tarayıcı UDP olmalıdır , bu yüzden bunları kullanarak enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM)(veya SOCK_DGRAMdüz eski soket programlama için) oluşturmanız gerekir
  • Sunucu "dinleyicisi" için, birden çok sunucunun aynı IP'de çalışabilmesi için bağlantı noktası adresinin enet_socket_set_option(socket, ENET_SOCKOPT_REUSEADDR, 1)(veya SO_REUSEADDR) kullanılarak yeniden kullanılmasına izin verin
  • İstemci "tarayıcısı" için, UDP soketindeki yayınları enet_socket_set_option(scanner, ENET_SOCKOPT_BROADCAST, 1)(veya SO_BROADCAST) kullanarak etkinleştirmelisiniz , aksi takdirde yayın adresine gönderemezsiniz. Bu, ağa yanlışlıkla su basmasını zorlaştırmak için yalnızca bir güvenlik özelliğidir .

Ne yazık ki bu tam olarak "hafif" bir çözüm değil; örnek proje, birkaç yüz LOC'de tamamen saatlerce çalışır. Bu, ENet için bir yardımcı program kitaplığına paketlenmiş olsaydı iyi olurdu, ancak oyun sunucuları için, bunu yararlı hale getirmek için genellikle sunucu yanıtıyla biraz daha oyuna özgü bilgi göndermek istediğinizi buldum:

  • Oyun türü (ör. "Kooperatif", "ölüm maçı")
  • Sunucunun çalıştığı "harita", "düzey" veya "kampanya"
  • Sunucu için oyuncu ve maksimum oyuncu sayısı
  • Danışanın bağlanma kararını etkileyecek ya da etmeyecek oyuna özgü diğer bilgiler. Oyunlardaki "sunucu tarayıcılarını" ve gösterdikleri bilgileri düşünün.

Tam da böyle düşünüyordum. Yayın yoludur.
Lolums

3

Kitaplığınızdan ayrılmak istemediğinizde, sadece kaba kuvvet uygulayabilir ve olası adreslerin her birine bağlanmayı deneyebilirsiniz. Çoğu ev ağı, IP adresinin ilk 24 bitinin aynı ve son 8 bitin farklı olduğu C Sınıfı ağlardır (/ 24). Yani sadece 255 olası IP adresiniz var.

Ama yine de, UDP yayını yapmak daha temiz bir alternatif olacaktır. 255.255.255.255'e bir UDP paketi gönderin, aynı yönlendiricinin arkasındaki tüm istemciler paketi alacaktır. Daha sonra göndereni hazır bulunduğunu bildirmek için paketin kaynak IP'sine ve kaynak bağlantı noktasına bir yanıt gönderebilirler.


2
Lütfen, lütfen lütfen lütfen lütfen kaba kuvvet saldırılarını yoktur.
Trevor Powell

@TrevorPowell ... çünkü ...?
Philipp

2
Çünkü bu yanlış bir çözüm. Üniversitelerde (c sınıfı ağları kullanmayan) veya işletmelerde (tipik olarak c sınıfı ağları kullanmayan) çalışmaz ve her ikisinde de BT personeli, her oyuncunun yapmasının neden olduğu yükü yoğun şekilde sevmez. brute-force, 'yenile' düğmesini her tıkladıklarında ağlarındaki her IP adresine mesaj göndermeye çalışır. Bu sadece soruna kötü bir çözüm . Potansiyel akranları bir matematik sunucusu olmadan bulma sorunu, tam olarak yayının ne olduğudur. Yayını kullanın. Her yönden daha iyi. :)
Trevor Powell

1

Sen bir göz olabilir DNS-SD / ZeroConf / Avahi / Bonjour / mDNS . Apple'ın yazıcıları, iTunes klasörlerini vb. Paylaşmak için kullandığı şeyler, ancak başka bir yerde kabul edildi. Avahi, Linux'un kullandığı açık kaynaklı sürümdür (yalnızca Linux olup olmadığından emin değilim), her şeyin ne kadar taşınabilir olduğundan emin değil (çoğu platform için uygulamalar olmasına rağmen).

Tüm bunları söyledikten sonra, UDP yayınını yapmak daha kolay olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.