Sieciowy Pong - lagi

Sieciowy Pong - lagi
TA
  • Rejestracja:prawie 18 lat
  • Ostatnio:około 13 lat
0

No więc chciałbym napisać sobie sieciowego ponga w klient-serwer (dwóch klientów). Zaimplementowałem sobie ruchy paletkami, tj. klient ruszając myszką powoduje ruch paletki i na bieżąco ją sobie maluje metodą repaint(), zaś Timer co ileś tam ms najpierw sprawdza, czy położenie paletki zmieniło się względem ostatniego sprawdzenia, jeśli tak, to wysyła pozycje jego paletki do serwera, serwer odsyła ją drugiemu klientowi. W localhoście wszystko śmiga aż miło, jednak gdy uruchamiam serwer na swoim koncie shellowym mam spore lagi.
Tutaj jest kod zadania timera (nr to numer klienta, 1 to klient z lewą paletką, 2 - z prawą, tab1 to położenie lewej paletki w pionie, tab2 - drugiej, dodam, że dataout jest typu DataOutputStream)

Kopiuj
class Zadanie extends TimerTask
{
public void run( )
{
        try
        {
           if ((nr==1)&&(tab1!=ostatni)) dataout.writeShort(tab1);
           if ((nr==2)&&(tab2!=ostatni)) dataout.writeShort(tab2);
        }
        catch (Exception e)
        {
            System.out.println(e);
        }
        if (nr==1) ostatni = tab1;
        if (nr==2) ostatni = tab2;
        repaint();
}
}

W tej sytuacji klient wysyła położenie paletki tylko gdy zmieniło się od poprzedniego sprawdzenia - w takiej konfiguracji mam lagi. Dziwną rzeczą jest fakt, że jesli klient nie sprawdza, czy położenie paletki zmieniło się, tylko wysyła cały czas w timerze co kilka ms (czyli w konsekwencji częstotliwość wysyłania jest dużo większa) to lagów paradoksalnie nie ma!

Tutaj przerobiona wersja zadania timera (wysyła dane bez sprawdzeń przy każdym "ticku" timera ,lagów nie ma):

Kopiuj
class Zadanie extends TimerTask
{
public void run( )
{
        try
        {
           if (nr==1) dataout.writeShort(tab1);
           if (nr==2) dataout.writeShort(tab2);
        }
        catch (Exception e)
        {
            System.out.println(e);
        }
        repaint();
}
}

Przecież nie powinienem zużywać łącza w przypadku, gdy nie ma takiej potrzeby. Jak rozwiązać ten problem?
Tu daję cały kod, fajnie, jakby ktoś przetestował:
http://www.speedyshare.com/files/27679645/Net_Pong.rar

edytowany 1x, ostatnio: Tamyl
Kerai
  • Rejestracja:ponad 16 lat
  • Ostatnio:ponad 2 lata
  • Lokalizacja:London
0

a robisz flush() ?

snout
  • Rejestracja:około 14 lat
  • Ostatnio:ponad 11 lat
  • Postów:37
0

jeśli masz użyte Timer na na obu klientach istniej pewien rodzaj synchronizacji klientów. Problem nie polega na tym, że przy Timerze bardziej obciążane jest łącze. Dla takiej gierki lagi powinny być minimalne (zawsze są). Ale np taka sytuacja:
nie masz timera, na jednym z klientów w tym samym czasie klasę do wyświetlanie che wywołać drugi klient oraz ruch pierwszego klienta. Nie jestem pewny jak zachowa się aplikacja.


Naród wspaniały, tylko ludzie ch..je:(
- wódz i kochany ojczulek narodu: Józef Piłsudski
TA
  • Rejestracja:prawie 18 lat
  • Ostatnio:około 13 lat
0

Kerai, mam flush po każdym write do outputstreama.
snout, chodziło mi o to, że Timer sprawdza, czy ostatnie położenie paletki różni się od obecnego, jeśli jest taki sam, to żadnych danych nie wysyła. Zatem Timer klienta wysyła na serwer dane tylko w momencie, gdy klient rusza paletką, jeśli klient przestaje ruszać paletką, to dane nie są wysyłane, czyli w konsekwencji serwer działa mniej więcej tak:

Kopiuj
>otrzymałem liczbę 300, wysyłam ją dalej
>otrzymałem liczbę 301, wysyłam ją dalej
>otrzymałem liczbę 302, wysyłam ją dalej

(tutaj klient przestaje ruszać paletką, więc serwer nic nie dostaje)

...

(tutaj klient znowu rusza paletką)
>otrzymałem liczbę 303, wysyłam ją dalej
>otrzymałem liczbę 304 wysyłam ją dalej

Dane do serwera dochodzą płynnie, bez większego opóźnienia, zaś u klienta, który odbiera dane ruch paletki przeciwnika mocno się tnie, jakieś 5 klatek/sek

Natomiast gdy wysyłam w Timerze położenie paletki non stop, np. co 5ms, lagów nie ma, wtedy serwer działa tak:

Kopiuj
>otrzymałem liczbę 300, wysyłam ją dalej
>otrzymałem liczbę 301, wysyłam ją dalej
>otrzymałem liczbę 302, wysyłam ją dalej (teraz klient przestaje ruszać paletką, mimo to serwer non stop wysyła położenia paletki do drugiego klienta)
>otrzymałem liczbę 302, wysyłam ją dalej
>otrzymałem liczbę 302, wysyłam ją dalej
>otrzymałem liczbę 302, wysyłam ją dalej
>otrzymałem liczbę 302, wysyłam ją dalej
>otrzymałem liczbę 302, wysyłam ją dalej (teraz klient znowu rusza paletką)
>otrzymałem liczbę 303, wysyłam ją dalej
>otrzymałem liczbę 304, wysyłam ją dalej
>otrzymałem liczbę 305, wysyłam ją dalej

Zrobiłem jeszcze taki test, że każda odebrana liczba od serwera np. przez klienta1 była dodawana do ListBoxa (chciałem zobaczyć, czy klient dostaje wszystkie dane, czy np co 5, co by łumaczyło lagi), podczas ruchu paletki klienta2 lista u klienta1 się "wieszała" na moment, zaś po tym odwieszeniu na liście u pojawiało się kilka nowych wartości, np 301,302,303,304,305, zatem klient otrzymuje wszystkie dane, tyle, że nie każdą po kolei, tylko po kilka w jednej "paczce"...

Naprawdę nie wiem jak sobie z tym poradzić, liczę na pomoc.

edytowany 1x, ostatnio: Tamyl
TA
  • Rejestracja:prawie 18 lat
  • Ostatnio:około 13 lat
0

Nikt nie poratuje? Co myślicie o przerobieniu Socketów na DatagramSockety i wysyłaniu paczek w oparciu o protokół UDP? Czy jest szansa, że to pomoże?

edytowany 1x, ostatnio: Tamyl
Kerai
  • Rejestracja:ponad 16 lat
  • Ostatnio:ponad 2 lata
  • Lokalizacja:London
0

Nie... rób to bez timera - on opóźnia wysyłanie...

TA
  • Rejestracja:prawie 18 lat
  • Ostatnio:około 13 lat
0

Początkowo miałem bez timera, wysyłałem dane w MouseMoved i miałem identyczne opóźnienia.

edytowany 1x, ostatnio: Tamyl

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.