2013-04-11 10 views
7

Pracuję nad aplikacją serwera/klienta udp.Tworzenie funkcji recv_from bez blokowania

Aby dowiedzieć się, czy któryś z klientów nie działa, serwer wysyła do klienta komunikat uzgadniania. Następnie serwer czeka na odpowiedź klienta, aby wysłać pewne dane, aby upewnić się, że klient jest aktywny. W tym celu serwer blokuje wywołanie do recvfrom(), chyba że klient odpowie, ale jeśli klient nie działa, serwer blokuje się w nieskończoność w rozmowie z numerem recvfrom().

Chcę zaimplementować taką funkcjonalność na moim serwerze, aby oczekiwała na wywołanie recvfrom() przez określony czas (powiedzmy 2 s). Jeśli żadne dane nie zostały odebrane od klienta w ciągu 2 sekund, klient jest uznawany za martwego i zwraca recvfrom().

Czy jest jakikolwiek sposób to zrobić? Przeszukałem internet, ale znalazłem rozwiązania takie jak ustawienie flagi MSG_DONTWAIT, która zwraca natychmiast po otrzymaniu żadnych danych, ale w moim przypadku nie chcę, aby recvfrom() natychmiast powrócił, ale czekał na dane przez określony czas, a gdy żadne dane nie otrzymały tego określony czas, funkcja recvfrom() powinna zostać zresetowana.

Każda pomoc jest doceniana.

+1

OK, chcesz wdrożyć niezawodną usługę. możesz ustawić funkcję [recvfrom()] (http://publib.boulder.ibm.com/infocenter/zos/v1r11/index.jsp?topic=/com.ibm.zos.r11.hala001/rcvf.htm) w tryb blokowania za pomocą funkcji [fcntl() lub ioctl()] (http://publib.boulder.ibm.com/infocenter/zos/v1r11/index.jsp?topic=/com.ibm.zos.r11.hala001/ rcvf.htm). Przeczytaj również [Implementacja niezawodnej usługi danych UDP] (http://stackoverflow.com/questions/8353970/udp-reliable-data-service-implementation) –

+1

Checkout ** [c - Ustaw limit czasu dla winsock recvfrom - Stack Overflow] (http://stackoverflow.com/questions/1824465/set-timeout-for-winsock-recvfrom)** –

+1

również [sprawdź] (http://msdn.microsoft.com/en-us/library/windows/desktop /ms740120%28v=vs.85%29.aspx) .it daje jasne wyjaśnienie w ** WSARecv() ** (ma reguły blokowania dla funkcji). –

Odpowiedz

8

Najprostszym sposobem byłoby użycie setsockopt(), aby ustawić limit czasu odbierania dla danego gniazda. Do tego celu służy

SO_RCVTIMEO.

Jeśli został ustawiony limit czasu dla gniazda przekazanego do recvfrom(), funkcja zwraca po tym czasie, jeśli żadne dane nie zostały odebrane.

Na przykład, aby ustawić 10 usec czytać Time-out (dodać sprawdzanie błędów na ReturnValue z setsockopt() jak to konieczne):

#include <sys/types.h> 
#include <sys/socket.h> 

... 

struct timeval read_timeout; 
read_timeout.tv_sec = 0; 
read_timeout.tv_usec = 10; 
setsockopt(socketfd, SOL_SOCKET, SO_RCVTIMEO, &read_timeout, sizeof read_timeout); 

Szczegółowe on Windows please see here i on Linux see here i/lub here (POSIX).

+0

Zadziałało, dziękuję bardzo :) – Ayse

+3

lub użyj 'select()', aby poczekać aż gniazdo wejdzie w czytelny stan w określonym limicie czasu, TO wywołaj 'recvfrom()' tylko wtedy, gdy gniazdo jest rzeczywiście czytelne, wskazując, że dane są dostępne do odczytu. –

+0

Po drugie używam 'select'. Uzyskujesz znacznie lepszą kontrolę i łatwiej jest upscale obsługiwać wiele gniazd. –

Powiązane problemy