Zbudowałem bibliotekę do programowania wyłącznie między platformami. Moje stworzone z nim gry działają dobrze w systemach Android, PC, Linux, Mac itp.
Możliwości sieciowe są zapewniane przez bibliotekę ENET, dlatego cała komunikacja między moimi aplikacjami nie jest kompatybilna z TCP ani UDP, ale tylko w niestandardowym protokole, nawet w ostateczności opartym na UDP.
Nie sądzę, aby można było robić to, co chcę z ENET, dlatego tutaj proszę o pomoc!
Powiedzmy, że mam tę samą grę na telefonie z Androidem, laptopie i komputerze. Wszystkie są w tej samej sieci Wi-Fi, a zatem w sieci LAN, niezależnie od tego, czy jest to hotspot Wi-Fi (?), Czy router domowy.
Potrzebuję każdego z tych 3 peerów, aby odkryć pozostałe dwa w sieci. Ma to na celu jedynie znalezienie adresu IP żywych aplikacji w sieci LAN, aby móc hostować między nimi gry wieloosobowe.
Mogę wymyślić tylko jeden skuteczny sposób na to, transmisję UDP, czekanie odpowiedzi, ale jeśli to jest rozwiązanie, potrzebuję czegoś małego, ponieważ jest to jedyny cel wdrożenia.
Innym sposobem może być próba połączenia się ze wszystkimi adresami IP w podzakresie adresu LAN, ale nie sądzę, aby system operacyjny był ze mną na tym: p
źródło
Odpowiedzi:
Jak wiele osób mówiło, rozwiązaniem byłoby użycie transmisji UDP , ale wiąże się to z wieloma szczegółami dotyczącymi implementacji. Niedawno napotkałem ten sam problem i po opracowaniu rozwiązania napisałem post na blogu oraz przykładowy projekt w postaci serwera / klienta czatu LAN. Podsumuję je tutaj, ale powinieneś sprawdzić je, aby uzyskać więcej szczegółów i prawdziwy kod.
Oto, jak to działa, na podstawie opisu Lee Salzman, twórcy ENet:
Dobrą wiadomością jest to, że ENet zapewnia funkcje otoki dla korzystania z gniazd , dzięki czemu możesz zrobić wszystko w ENet. Zła wiadomość jest taka, że opakowanie jest wyjątkowo cienkie; musisz wiedzieć o programowaniu gniazd , na przykład o tym, co
select()
robi. Dlatego zachęcam do przejrzenia posta na blogu i przykładowego projektu , abyś mógł skopiować / wkleić kod i zaoszczędzić sobie dużo czasu.Oto kilka uwag i pułapek, jeśli zdecydujesz się na własną implementację:
enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM)
(lubSOCK_DGRAM
do zwykłego programowania starego gniazda)enet_socket_set_option(socket, ENET_SOCKOPT_REUSEADDR, 1)
(lubSO_REUSEADDR
), aby wiele serwerów mogło działać pod tym samym adresem IPenet_socket_set_option(scanner, ENET_SOCKOPT_BROADCAST, 1)
(lubSO_BROADCAST
), w przeciwnym razie nie można wysłać na adres rozgłoszeniowy. Jest to tylko funkcja bezpieczeństwa , która utrudnia przypadkowe zalanie sieci.Niestety nie jest to rozwiązanie „lekkie”; przykładowy projekt osiąga w sumie kilkaset LOC. Byłoby miło, gdyby zostały one spakowane do biblioteki narzędziowej dla ENet, ale zauważyłem, że w przypadku serwerów gier często chcesz wysłać więcej informacji specyficznych dla gry wraz z odpowiedzią serwera, aby były one przydatne, takie jak:
źródło
Kiedy nie chcesz opuszczać biblioteki, możesz po prostu użyć brutalnej siły i spróbować połączyć się z każdym z możliwych adresów. Większość linii domowych to sieci klasy C (/ 24), w których pierwsze 24 bity adresu IP są takie same, a ostatnie 8 bitów różnią się. Masz więc tylko 255 możliwych adresów IP.
Nadal jednak transmisja UDP byłaby czystszą alternatywą. Wystarczy wysłać pakiet UDP na numer 255.255.255.255, a otrzymają go wszyscy klienci za tym samym routerem. Następnie mogą wysłać odpowiedź na źródłowy adres IP i źródłowy port pakietu, aby poinformować nadawcę, że są obecni.
źródło
Możesz rzucić okiem na DNS-SD / ZeroConf / Avahi / Bonjour / mDNS . Jest to rzecz, której Apple używa do udostępniania drukarek, folderów iTunes i tak dalej, ale została zaadaptowana gdzie indziej. Avahi jest wersją opensource używaną przez Linuksa (nie jestem pewien, czy to tylko Linux), nie jestem pewien, jak przenośna jest cała rzecz (chociaż istnieją implementacje dla większości platform).
Powiedziawszy to wszystko, prawdopodobnie łatwiej jest po prostu przeprowadzić transmisję UDP.
źródło