Skocz do zawartości

Zły odebrany pakiet


Sutikku

Rekomendowane odpowiedzi

Ostatnio się trochę więcej bawię gmsowym networkingiem i ciągle mam nowe problemy. W sumie ten problem doświadczam od zawsze. Przyjmijmy, że po stronie serwera wysyłam do wszystkich klientów

1 <-id komendy

23 <- x

12 <- y

Wszystkie trzy są zapisane jako buffer_u8. I jednemu z klientów wyrzuca błąd, po którym można wywnioskować, że odebrane dane to

0

-102

xxx

Oczywiście te liczby to przykłady, ale takie coś jest powiedzmy znacznym problemem. I nigdy nie występuje u mnie jak testuje, tylko dopiero gdy testuje to z kimś innym. I tak się zastanawiam. Czy jeśli w ciągu jednego stepu, użyję dla jednego klienta dwa razy network_send_packet(), to może to być problemem?

edit:

natrafiłem na coś takiego

http://gmc.yoyogames.com/index.php?showtopic=650252

i z tego co rozumiem, czasem pakiety są "ucięte", a następnie dostaje to co zostało ucięte. I nie wiem jak sobie z tym radzić.

Odnośnik do komentarza
Udostępnij na innych stronach

Nah, z lenistwa czasami jeden po drugim wysyłam kilka oddzielnych pakietów. Zero problemów.

Jeżeli taki sam rodzaj danych jest wysyłany i odbierany i pamiętasz o buffer_seek oraz aby podać odpowiednią wielkości bufora, nie powinno być problemu.

Używasz UDP czy TCP?

Odnośnik do komentarza
Udostępnij na innych stronach

Żadne tam tajne, wysłałbym nawet cały projekt, ale jakby ktoś zobaczył kod, to wstyd ;d

GML
///Wysyłanie pozycji

buffer_seek(Buffer, buffer_seek_start, 0)

buffer_write( Buffer, buffer_s8, 1 );

buffer_write( Buffer, buffer_u8, instance_number(obj_player) );

with(obj_player)

{

buffer_write( other.Buffer, buffer_u8, iid );

buffer_write( other.Buffer, buffer_u16, x );

buffer_write( other.Buffer, buffer_u16, y );

buffer_write( other.Buffer, buffer_u8, image_angle/2 );

buffer_write( other.Buffer, buffer_bool, key

);

buffer_write( other.Buffer, buffer_bool, key[UP] );

buffer_write( other.Buffer, buffer_bool, key

);

buffer_write( other.Buffer, buffer_bool, key[DOWN] );

}

for(var i=0; i<MaxClients; i++)

{

if!(player==-1)

network_send_packet( i, Buffer, buffer_get_size(Buffer) );

}

To jest najczęstszy kod który się wykonuje w kwestiach wysyłania.

A odbieram tak

GML
var type_event = ds_map_find_value( async_load, "type" );

 

switch( type_event )

{

case network_type_data:

var buffer = ds_map_find_value( async_load, "buffer" );

buffer_seek( buffer, buffer_seek_start, 0 );

ReceivedPacket( buffer );

break;

}

I jeszcze skrypt ReceivedPacket (okrojony)

GML
var buffer = argument[0];

var msgid = buffer_read( buffer, buffer_s8 );

switch( msgid )

{

case 1:

//Zmiana pozycji graczy

var num=buffer_read( buffer, buffer_u8 );

for(var i=0; i<num; i++)

{

var iid=buffer_read( buffer, buffer_u8 );

var xx=buffer_read( buffer, buffer_u16 );

var yy=buffer_read( buffer, buffer_u16 );

var ang=buffer_read( buffer, buffer_u8 );

var p=player[iid];

var right=buffer_read( buffer, buffer_bool );

var up=buffer_read( buffer, buffer_bool );

var left=buffer_read( buffer, buffer_bool );

var down=buffer_read( buffer, buffer_bool );

break;

}

Kodu trochę mam, więc nie wiem co dokładnie mam pokazać. Każde miejsce w którym wysyłam i odbieram?

Odnośnik do komentarza
Udostępnij na innych stronach

W odbieraniu nie używaj buffer_seek

(^ rozwiązanie problemu, reszta postu to moje pieprzenie)

Buffer automatycznie jest odczytywany od startu a wartości odczytanę są usuwane.

Dlatego też, np. jeżeli danych z bufera potrzebujesz kilka razy użyć zapisuj je do zmiennych.

 

@semi-offtop

polecam zamiast

GML
var buffer = ds_map_find_value( async_load, "buffer" );

ReceivedPacket( buffer );

robić po prostu

GML
ReceivedPacket(async_load[? "buffer"]);

Accesory to użyteczna magia

Odnośnik do komentarza
Udostępnij na innych stronach

Nie sprawdziłem jeszcze czy to rozwiązanie, ale pewnie tak.

A mam takie pytanie, czemu to tak działa, że ja sam tego problemu nie mam? Routery same "obcinają" pakiety, by zwiększyć szybkość odbierania danych?

Odnośnik do komentarza
Udostępnij na innych stronach

GML
switch( msgid )

{

case 1:

//Zmiana pozycji graczy

var num=buffer_read( buffer, buffer_u8 );

for(var i=0; i<num; i++)

{

var iid=buffer_read( buffer, buffer_u8 );

//...

var down=buffer_read( buffer, buffer_bool );

break;

}

Zjadłeś klamrę przy kopiowaniu kodu, powinno wyrzucić błąd albo powinno przerwać pętlę zanim "i" osiągnie wartość 1.

 

Przy tworzeniu buffera (bufora?) precyzujesz parametr "alignment", co może mieć znaczenie przy używaniu buffer_seek, gdy używasz buffer_write z różnymi typami danych (np. bool i u32). Typowo ma on wartość 1.

Odnośnik do komentarza
Udostępnij na innych stronach

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ę...