2013-05-02 20 views
5

Buduję prostą aplikację przy użyciu c, który był używany recvmmsg(), a piątym parametrem jest limit czasu wynoszący type struct timespec. Ustawiłem limit czasu na 5 sekund, ale to nie działa, blokuje nieskończoność.Jak ustawić limit czasu w recvmmsg()?

Kod jest jak następuje:

struct timespec timeout; 

timeout.tv_sec = 5; 
timeout.tv_nsec = 0; 

result = recvmmsg(fd, datagrams, BATCH_SIZE, 0, &timeout); 
+1

Istnieje sugestia dotycząca możliwego błędu, który może być istotny: http://lists.openwall.net/netdev/2012/12/23/30 – Vicky

+0

@Vicky: To jest prawo - podobne do linku w moim odpowiedź. Nie jest jednak jasne, czy ktokolwiek zmienił zachowanie - bardziej prawdopodobne, że zostanie to uznane za błąd w dokumentacji, strona podręcznika będzie zaktualizowana, a niemal bezużyteczny parametr limitu czasu po prostu nie będzie używany przez większość aplikacji. –

+0

jest inne rozwiązanie w powyższym linku, używając: http://stackoverflow.com/questions/12713438/how-to-add-delay-to-sento-and-recvfrom-in-udp-client-server-in- c – MOHAMED

Odpowiedz

4

Alternatywnie można użyć opcji setsockopt z opcją SO_RCVTIMEO, aby ustawić limit czasu dla gniazdo elektryczne. Wpływa to na wszystkie wykonywane na nim operacje odczytu.

5

Zobacz tutaj: http://permalink.gmane.org/gmane.linux.man/3440

Zasadniczo parametr Timeout określa maksymalną ilość czasu, aby czekać na więcej wiadomości, ale pod spodem otrzymać operacja jest nadal blokuje . Jeśli więc ustawisz limit czasu wynoszący 5 sekund i otrzymasz jedną wiadomość co sekundę, zatrzyma się po odebraniu (około) 5 wiadomości, nawet jeśli w buforach jest więcej miejsca. To, czego nie zrobi, to wrócić po 5 sekundach, jeśli w ogóle nie ma danych. W tym celu powinieneś użyć jednego ze zwykłych mechanizmów, takich jak select() lub epoll() z limitem czasu, lub zajętym czekaniem itp.

+0

Naprawdę nie mogę sobie wyobrazić użycia, jeśli jest to użyteczne i zamierzone. – PlasmaHH

+0

Z tego linku tej odpowiedzi wynika, że ​​cytat jest bardzo ilustracyjny: "recvmmsg() ma jawny parametr timeout, ale nie wygląda na to, że działa poprawnie, a dokumentacja nie wspomina, w jaki sposób ma oddziaływać z SO_RCVTIMEO. " Było to pomocne, ponieważ wyjaśnia, dlaczego MUSISZ ustawić parametr 'SO_RCVTIMEO' gniazda, jeśli chcesz, aby parametr timeout' recvmmsg() 'nie blokował się w nieskończoność. (Mój kod testowy recvmmsg (z 'man recvmmsg') blokuje się na czas nieokreślony z czasem oczekiwania wynoszącym 1 s. Jeśli ustawisz SO_RCVTIMEO na gniazdo, to nie blokuje się w nieskończoność). –

0

Jest błąd w implementacji recvmmsg:

Wskazówki, pselect pozwalają sprawdzić, czy dane są dostępne. Jednak nie gwarantuje, że recvmmsg nie będzie czekać na zawsze. Dlatego nie używaj tej metody.

Proponuję użyć parametru SO_RCVTIMEO jako parametru recvmmsg w postaci timeout. recvmmsg zostanie zakończony, jeśli żadne dane nie zostały odebrane od SO_RCVTIMEO lub po timeout. W najgorszym przypadku recvmmsg zostanie zakończony po timeout + SO_RCVTIMEO (przypadek, w którym dane są odbierane tuż przed końcem timeout i żadne dane nie są już dostarczane).

Powiązane problemy