2012-09-03 27 views
21

W moim skrypt Pythona, mam aktywować TCP keepalive poleceniem:Jak zmienić licznik keepcive tcp za pomocą skryptu python?

x = s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) 

Moim celem jest połączenie gniazda, aby zamknięte, jeśli nie ma transmisji (*) przez 5 minut. Pracuję w systemie Windows, a mój skrypt python pobiera i nie przesyła żadnych danych do programu klienta.

Wiem, że domyślnie, jeśli żadna transmisja nie będzie dostępna przez 2 godziny, wtedy tylko ja mogę zamknąć połączenie używając try i except. Wiem, że w przypadku okien mogę ręcznie zmniejszyć czas oczekiwania, przechodząc do rejestru. Ale czy istnieje sposób, w jaki mogę go zmodyfikować z mojego scenariusza?

(*) tutaj "brak transmisji" oznacza "coś po cichu zjada pakiety w sieci", a nie "Nie próbuję niczego wysłać."

+0

wyjaśnić co "brak transmisji" oznacza. –

Odpowiedz

-5

Keepalive to sztuczka protokołu TCP do wykrywania martwych połączeń, np. dla serwera Telnet. Domyślnie jest wyłączone. Aby zmienić czas aktywności, użyj socket.setsockopt. Zobacz https://docs.python.org/2/library/socket.html

+2

Twoja odpowiedź jest błędna. –

+0

Absurdalnie niepoprawnie –

+0

Nawet okna mają następujące opcje: http://msdn.microsoft.com/en-us/library/windows/desktop/ee470551(v=vs.85).aspx –

45

Możesz ustawić liczniki czasu podtrzymania TCP na już otwartym gnieździe za pomocą setsockopt().

import socket 

def set_keepalive_linux(sock, after_idle_sec=1, interval_sec=3, max_fails=5): 
    """Set TCP keepalive on an open socket. 

    It activates after 1 second (after_idle_sec) of idleness, 
    then sends a keepalive ping once every 3 seconds (interval_sec), 
    and closes the connection after 5 failed ping (max_fails), or 15 seconds 
    """ 
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) 
    sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, after_idle_sec) 
    sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, interval_sec) 
    sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, max_fails) 

def set_keepalive_osx(sock, after_idle_sec=1, interval_sec=3, max_fails=5): 
    """Set TCP keepalive on an open socket. 

    sends a keepalive ping once every 3 seconds (interval_sec) 
    """ 
    # scraped from /usr/include, not exported by python's socket module 
    TCP_KEEPALIVE = 0x10 
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) 
    sock.setsockopt(socket.IPPROTO_TCP, TCP_KEEPALIVE, interval_sec) 

Dla równoważnych opcji w oknach refer to msdn. Patrząc przez Python source, wydaje się, że musisz ustawić SO_KEEPALIVE z sock.setsockopt podobną do Uniksa i [opcjonalnie?] Ustawić SIO_KEEPALIVE_VALS z sock.ioctl.

+0

Należy pamiętać, że używane tu stałe TCP_ * są specyficzne do Linuksa. Na przykład nie są dostępne w OS/X – RobM

+1

osx 'man tcp' zawiera opcję' TCP_KEEPALIVE', która akceptuje sekundy pomiędzy sondami, co jest równoważne 'TCP_KEEPINTVL' w systemie Linux. opcja nie jest eksportowana w Pythonie 2.7 lub 3.3, ale myślę, że możliwe jest użycie prawidłowej wartości całkowitej "0x10" jako klucza. –

+0

@DimaTisnek TCP_KEEPINTVL wygląda na równoważny, ale jak dostałeś tę wartość '0x10'? –

7

dla Windows, w Pythonie:

Gniazdo pozwoli utrzymać przy życiu, z 10 sekund podtrzymanie czasu i 3 sekundy zachować odstęp żyje.

sock.ioctl(socket.SIO_KEEPALIVE_VALS, (1, 10000, 3000)) 

Więcej szczegółowych informacji here