Skocz do zawartości

Problem z przesyłaniem pozycji za pomocą UDP.


Arkarius

Rekomendowane odpowiedzi

Witam, ostatnio robię projekt z użyciem 39dll. Obczaiłem juz połączenia TCP, okazało się jednak, że do przesyłania pozycji gracza 3 - 4 razy na step jest to niewystarczające. Wyczytałem, że UDP jest szybsze ale może gubić pakiety itp. Mimo to zacząłem coś z tym UDP działać, (a miałem już to chodzenie zrobione na TCP dla dowolnej liczby klientów + serwer) na takiej samej zasadzie jak TCP a mianowicie:

1. Klient łączy sie z serwerem przez tcpconnect.

2. Serwer akceptuje połączenie, tworzy u siebie gracza, nadaje mu ID, nadaje tej swojej kopii socket zwrócony przez udpsock1 = udpconnect(14805,1), wysyła ID do klienta.

3. Klient tworzy postać z przysłanym ID.

4. Serwer dodaje gracza który sie właśnie połączył do klientów pozostałych graczy oraz pozostałych graczy do tego klienta. (Wszystko przez TCP)

5. Klient tworzy swojego socketa przez udpsock2 = udpconnect(14803,1) i wysyła nim swoje x i y na serwer sendmessage(udpsock2, "127.0.0.1", 14805)

6. Serwer odbiera x i y klienta przez receivemessage(udpsock1) i odsyła do innych graczy sendmessage(udpsock2, "127.0.0.1", 14803) - rozróznia ich po ID.

(x i y jest dla przykładu, bo ja tam więcej zmiennych przesyłam)

I tu pojawia się problem, przesyłanie x i y na serwer działa mi tylko przy jednym graczu, a jak dołącze drugiego klienta, to serwer nie tworzy dla swojej kopii tego klienta socketa przez udpconnect (sprawdzałem wynosi on -1).

I teraz pytania:

- czy wogóle UDP działa na takiej samej zasadzie jak TCP czyli klient - serwer - pozostali gracze?

- jeśli nie to jak powinno wyglądać przesyłanie pozycji gracza za pomocą UDP? (zaznacze, że szukałem ale jedyne co znalazłem to przykłady z TCP albo pong dla 2 graczy dołączony do 39dll)

Nie wiem czy opisałem to w sposób zrozumiały nie chciałem dawać kodu bo po pierwsze jest go dużo i mogłoby to jeszcze bardziej zamieszać a po drugie jest prawdopodobnie mało czytelny dla osoby drugiej.

Jeśli ktoś by się pokusił o mini-przykładzik przesyłania pozycji od klienta na serwer i do reszty klientów dla 2+ graczy przez UDP to byłbym wdzięczny.

Odnośnik do komentarza
Udostępnij na innych stronach

Już wyjaśniam!

 

Jestem jedną z pierwszych, jeśli nie pierwszą osobą, która użyła 39dll'a na GMclanie, więc możesz być pewny moich informacji i doświadczeń :P.

Do rzeczy:

Socket UDP dla jednego adresu IP może zostać otwarty TYLKO 1 raz. Zauważ, że TCP nie wymaga podania adresu IP przy wysyłaniu informacji.

Tak więc aby móc testować swoją grę samemu na 1 kompie, musisz postarać się o pewien system, o którym mowa dalej.

 

Dodatkowo, należy wiedzieć, że sockety UDP mogą zostać otwarte tylko dla osób ze publicznym adresem IP. Jest to taki adres jaki masz w rzeczywistości. Najczęściej się go posiada mając połączenie w neostradzie itp. W sieciach osiedlowych, które roszczą usługi tylko np. w wybranymmieście na wybranych osiedlach, z reguły jesteś podłączony do jakiejś jednej większej sieci lokalnej i twój adres IP jest adresem w tej sieci lokalnej, a to co widzisz na stronie takiej jak "whatsmyip.com" jest to adres IP do urządzenia rozdzielającego internet między was wszystkich. Stąd brak możliwości hostowania gier, lub otrzymywania danych przez socket UDP (gdyż wymaga on wysłania inf. pod dany port i adres ip).

 

Co to znaczy dla ciebie jako twórcy gry? Tzn. że musisz sprawdzać gracza, który właśnie dołączył, próbując wysłać mu wiadomość po porcie UDP i czekać na odpowiedz. Jeśli nie ma odpowiedzi powiedzmy, w przeciągu 5 sekund. Zmieniasz mu priorytet i WSZYSTKIE dane wysyłasz przez TCP. Jeśli odpowiedź jest, wysyłasz po udp to co trzeba.

W moich grach ten system się sprawdził. Pierwszy raz użyłem go w Mario Kart Online, aczkolwiek nigdy nie ukończyłem projetku :P.

 

Mam nadzieję, że wyjaśniłem kwestię.

Pozdro.

Odnośnik do komentarza
Udostępnij na innych stronach

Dołączę się do tematu, sam chciałem identyczny założyć i ten rozwiązał mój problem. i takie pytanie...

Czy jak ja robię grę, gdzie UDP jest mi potrzebne tylko do wysyłania z serwera do klientów, to nie będę mógł zagrać jako klient nie mając publicznego IP ?

Bo z tego co widzę to trzebabyłoby przekierować porty, z czym ja nie mam problemu, ale są przypadki gdzie to dostawca internetu daje wewnętrzne IP.

Jest jakaś możliwość żeby tacy też mogli zagrac ? jakieś porty UDP co dostawcy internetu zawsze przekierowują albo coś (przepraszam za moją niewiedzę na ten temat jak cos :P)

Piszesz o zmianie priorytetu. Ale z tego co widzę jak w TCP przesyłam co step, to skutki są jakie są, nie nadąża :D chyba że to się da jakoś ominąć ? wysyłanie rzadziej nie wchodzi w gre. musi być jakiś sposób. Przecież tyle gier jest przez TCP i działa ładnie.

Z góry dzięki za odpowiedź.

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

Btw. z tego co pamiętam, to serwer i tak musi mieć zew. IP, więc UDP idzie w obie strony, natomiast w przypadku graczy, to często mogą oni nadawać UDP, ale danych tych nie odbiorą. Dlatego też warto chociaż do serwera dane wysyłać przez UDP (wiem, to upload jest ważniejszy, bo te są zawsze mniejsze, ale niestety, trzeba korzystać z TCP które nadaje większą ramkę danych).

Odnośnik do komentarza
Udostępnij na innych stronach

Dzieki za zainteresowanie tematem.

Mam zrobione że klient przesyła stan klawiszy przez TCP, a serwer odsyla pozycje, kierunki postaci i musi to robic przez UDP, bo postac sie ma plynnie poruszac. I calkiem nieźle to chodzi przez UDP. Ale z tego co widze to nie ma sensu, bo nie bedzie kazdy gracz sobie przekierowywal portów, bo to nie ma sensu.

Więc jak zrobić zeby bylo plynnie przez TCP, jak w nim trzeba przesyłać rzadziej bo nie nadąża (troche zszedlem z tematu przepraszam).

Jak sie to robi zeby to było dokładne i płynne ?

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

Postać porusza się płynnie, jak nie ustawiasz jej x = readshort(); tylko każesz jej iść do tego punktu (np. nadanie wektora (speed + dir to point xdocelowe,ydocelowe), mp_potential_step - wtedy jest tylko lekkie opóźnienie spowodowane wysłaniem i odebraniem danych.

Odnośnik do komentarza
Udostępnij na innych stronach

Wysyłanie stanu klawiszy to okropny sposób. W ogole sie nie sprawdza. A wysyłanie co step to horror. Nigdy nie powinno się tego tak robić. Są specjalne sposoby jak wysyłać dane rzadziej z tą samą precyzją.

 

Co do portów to wykonanie testu dla każdej nowo połączonej osoby a następnie:

Serwer wysyła po UDP tam gdzie się da, gdzie się nie da to TCP.

Klienci do serwera zawsze mogą po UDP.

Odnośnik do komentarza
Udostępnij na innych stronach

ja też robię właśnie grę i do każdej zmiennej z osobna w serwerze (x, y, image_angle) dałem jeszcze drugą zmienną, która przechowuje 0 jeżeli serwer nie odebrał zmiennej x np lub 1 jeżeli odebrał, i wtedy przy wysyłaniu jak jest 1 to rozsyła, a w kliencie po prostu jak się x zmieni to wysyła x, ale do image_angle mam wątpliwości, chyba zrobię że jeżeli się zmienia to powiedzmy co sekunde ma wysyłac image_angle i wtedy u reszty graczy z obecnego się przekręca do tego które odebrano

Odnośnik do komentarza
Udostępnij na innych stronach

  • 1 miesiąc temu...

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...