Wpis z mikrobloga

#cpp #programowanie

Jak to jest powiedzcie mi:

recvfrom(fd, buffer, 1, 0, cliaddr, &len);


Jeśli hipotetycznie otrzymałem datagram o długości np. 10 bajtów, a ja pobieram sobie w pętli po jednym znaku (sprawdzam czy dany znak to umówiony znak 'stopu'), to cliaddr nadpisuje się za każdym razem. Powiedzcie mi tylko jak to działa? Czy każdy bajt w buforze ma przypisane informacje o EndPoincie z któergo przyszedł, czy cały zakres bajtów czy jak? A może po prostu aż do przyjęcia EOFa buffer zawiera tylko jeden datagram? Po prostu chciałbym uniknąć sytuacji w której datagramy pomieszają się tak że nagle zacznę pobierać bajty które przyszły od kogoś innego i nadpisze mi się struktura. ;_;
  • 6
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

@bartoneczek: Tak na zdrowy rozsądek to wszystkie bajty od jednego nadawcy nie mają prawa pomieszać się z bajtami od innego (tj. jak czytasz po bajcie to w pewnym momencie cliaddr się zmieni (prawdopodobnie, każdy sender ma osobny bufor)). W takim przypadku można użyć connect() na gniazdach datagramowych (i potem recv()/read()), co spowoduje, że odbierane będą datagramy tylko od partnera, z którym robiono connect().
  • Odpowiedz
@bartoneczek: to może ustaw protokół tak, by w komunikacie na starcie było info o długości danych (bądź stała długość). Smutno patrzeć na każdorazowe wywołanie recv() co jeden bajt (wydajność klęka). Możesz to co otrzymać sobie zbuforować i z tego bufora chapać po bajcie (będzie znacznie szybciej niż przez syscall). Jak duży rozmiar bufora byś nie podał to system nie ma prawa w jednym wywołaniu zwrócić danych od dwóch partnerów.
  • Odpowiedz
@bartoneczek: sprawdziłem w aplikacji jak to się zachowuje i tu jest o tyle ciekawie, że każde recvfrom() odczyta jeden bajt po czym cała reszta komunikatu jest odrzucana i przy następnym wywołaniu recvfrom() program blokuje (chyba że w międzyczasie przyszedłby kolejny datagram). Stąd też pewnie główna różnica między gniazdami strumieniowymi a datagramowymi, które bardziej przypominają zachowaniem kolejki komunikatów.
  • Odpowiedz
@deekox: rzeczywiście, teraz doczytałem:

This call returns the length of the incoming message or data. If a datagram packet is too long to fit in the supplied buffer, datagram sockets discard excess bytes.


Czyli mój sposób pobierania danych po jednym bajcie jest nie tylko mało wydajny, ale też po prostu nie działa. ;_;
  • Odpowiedz