Jak mogę spróbować odczytać dane z gniazda z przekroczeniem limitu czasu? Wiem, select, pselect, poll, ma pole limitu czasu, ale ich użycie wyłącza "tcp fast-path" w stosie tcp reno.
Jedyny pomysł, jaki mam, to użycie recv (fd, ..., MSG_DONTWAIT) w pętli
Odpowiedzi:
Możesz użyć funkcji setsockopt, aby ustawić limit czasu dla operacji odbierania:
Podobno w systemie Windows należy to zrobić przed wywołaniem
bind
. Eksperymentalnie potwierdziłem, że można to zrobić przed lub pobind
w systemie Linux i OS X.źródło
struct timeval tv;
czy oznacza to, że funkcja select () też nie będzie działać? Próbowałem przenieść mój kod select () do systemu Windows i natychmiast przekroczył limit czasu, wygląda na to, że ignoruje wartość, którą ustawiam w timeval.Oto prosty kod dodający limit czasu do
recv
funkcjipoll
w języku C:źródło
poll
będzie czekał na odebranie co najmniej jednego bajtu lub przekroczenia limitu czasu, podczas gdy podczas wywoływaniarecv
funkcji będzie czekał nasizeof(buf)
bajty, powodując jej ponowne zablokowanie, jeśli ten licznik jeszcze nie nadszedł, ale tym razem bez przekroczenia limitu czasu.// działa również po operacji wiązania dla WINDOWS
źródło
Zainstaluj moduł obsługi dla
SIGALRM
, a następnie użyjalarm()
lubualarm()
przed zwykłym blokowaniemrecv()
. Jeśli alarm sięrecv()
włączy, zwróci błąd zerrno
ustawieniem naEINTR
.źródło
LINUX
WINDOWS
UWAGA : To ustawienie zostało wprowadzone przed
bind()
wywołaniem funkcji dla prawidłowego uruchomieniaźródło