2010-11-16 11 views
5

Piszę aplikację sieciową, która używa ASIO/UDP do wysyłania i odbierania między jedną parą zdalną/locale punktu końcowego. Użyłem polecenia udp :: socket :: receive do odbioru danych i wszystko w moim kodzie działało logicznie, ale traciłem ogromną liczbę pakietów. Odkryłem, że każdy odebrany pakiet, który nie został zablokowany w funkcji odbioru, został utracony - nie buforował. Było to szczególnie dziwne, bo ja ustawić bufor do 2MB otrzymane za pomocą następującego polecenia:Zwiększenie buforowania ASIO nie działa

sock_udp.connect(remote_endpoint); 
sock_udp.set_option(boost::asio::socket_base::receive_buffer_size(2*1024*1024)); 

To oraz fakt, że jeśli wysłałem tylko dwa pakiety około 100 bajtów, by każdy nadal tracić drugi gdybym spędził w dowolnym momencie przetwarzanie pierwszego.

Doszedłem do wniosku, że być może jest to usterka z udp :: socket :: receive, więc ponownie napisałem swój kod sieciowy, aby użyć udp::socket::async_receive, ale nadal mam ten sam problem. Oznacza to, że gdy mój program obsługi zostanie wywołany, usuwam wszystkie pakiety, dopóki nie wezwę ponownie async_receive.

Czy zasadniczo coś nie rozumiem? Czy istnieje inne podejście, które powinienem stosować, aby zwiększyć buforowanie przychodzących pakietów?

Jeśli to pomaga, sprawdziłem, że dzieje się to zarówno w systemie OS X w XCode przy użyciu ich niestandardowej wersji gcc4.2, jak i Ubuntu 10.10 przy użyciu gcc4.5. Nie mogłem go wypróbować w systemie Windows.

+3

może możesz zamieścić pełniejszy przykład, trudno powiedzieć z Twojego opisu, co może być nie tak, użyłem 'boost :: asio :: async_read' z udp gniazdami i nie miałem problemów z upuszczaniem pakietów ... – Nim

+1

, jak powiedział Nim, powinieneś opublikować więcej kodu, aby dać nam lepszy pomysł na strukturę Twojego programu. –

Odpowiedz

2

Ogólna koncepcja polega na tym, że twój program powinien spędzić ogromną większość czasu oczekiwania na gniazdo, aby coś dostarczyć, albo zablokować w UDP odbierać lub czekać w io_service na powiadomienie, że gniazdo coś asynchronicznie otrzymało. Gniazdo niejawnie ma mały bufor w systemie operacyjnym do odbierania pakietów, nie ma sposobu, aby tego uniknąć. Tak więc problem jest bardziej prawdopodobny w sposobie działania programu.

  • Czy Twój nić znajduje się poza serwisem ASIO io_? Jeśli tak, możesz łatwo przepełnić dowolny bazowy bufor gniazda.
  • Czy możesz udowodnić, że średni czas między zablokowaniem połączeń jest krótszy niż czas między wysłaniem pakietów?
  • Musisz ponownie wywołać async_receive po otrzymaniu danych z gniazda. Na przykład możesz wystawić inny async_receive z twojej obsługi odbioru.
+1

Powodem, dla którego oznaczyłem to jako odpowiedź, jest to, że błąd okazał się błędem PEBKAC (problem występuje między klawiaturą a krzesłem). Niektóre fragmenty kodu były robione w różnych wątkach, a gdy dane docierały zbyt szybko, pisałem. Odkryłem to, próbując wymyślić krótki przykład - a przykład nie wykazał błędu. – Jonathan

Powiązane problemy