socket timeout verändern um nw unterbrechungen zu erkennen

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Benutzeravatar
limepix
User
Beiträge: 37
Registriert: Dienstag 11. November 2008, 16:54

Moin.

Folgendes Problem: Ich möchte zwischen zwei Rechnern, die in verschiedenen Netzen hängen (d.h. nicht dass die unbedingt übers Internet miteinander verbunden sind), welche NICHT unter meiner Administration stehen die Leitung auf kurze Ausfälle überprüfen. Als Testverfahren dachte ich an einen einfaches Socket Server Client Konstrukt.
Ich hab das hier mal in unserem Firmennetz zwischen Rechner probiert und festgestellt, dass ich, nachdem ich mein Netzwerkstecker gezogen hab´, erst einen Fehler nach ca. 8 Sekunden bekomme. Meine Vermutung ist, dass das mit der Eigenschaft " SO_KEEPALIVE = 8 "
zu tun hat. Lieg ich da richtig?

Ich bin mal davon ausgegangen, dass das der Teil is der dieses "Timeout" beeinflusst und habs versucht folgendermaßen zu verändern:

server.py

Code: Alles auswählen

import time
import socket

HOST, PORT = '', 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)

conn, addr = s.accept()

print 'verbunden: ', addr
while 1:
    data = conn.recv(1024)
    if not data: break
    conn.send(data)

client.py

Code: Alles auswählen

import time
import socket

HOST, PORT = '172.16.1.123', 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 0)
s.connect((HOST, PORT))
try:
    while 1:
        s.send(time.strftime('%Y-%m-%d %H:%M:%S'))
        data = s.recv(1024)
        print 'Received', repr(data)
        time.sleep(1)
except:
    print 'Connection lost'
finally:
    s.close()
naja... weswegen ich frag is die tatsache, zum einen weil das nichts gebracht hat - ich bekomm den fehler immer noch erst nach 8 sekunden und zum andern, dass ich in der msdn folgenden hinweis zu SO_KEEPALIVE gefunden hab der mich nun "leicht" verwirrt...:

SO_KEEPALIVE BOOL Sends keep-alives. Not supported on ATM sockets (results in an error).

und jetz nich sicher bin wie ich verlässlich behaupten kann, dass die verbindung (auch wenns nur ne halbe sekunde is(das würde ich gern einstellen)) weg ist.

danke schon mal für antworten
grüß
limepix
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Gibt's einen Grund, das nicht über ICMP messages (aka PING) zu machen? Und: Wie klein soll denn das Intervall werden, kleiner noch als 500ms? Das ist vermutlich möglich, du würdest aber eine sehr hohe Netzbelastung herstellen. Geht's hier um Hochverfügbarkeit?
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Wie wärs mit socket.settimeout(float) ?!
http://docs.python.org/library/socket.h ... settimeout
Benutzeravatar
limepix
User
Beiträge: 37
Registriert: Dienstag 11. November 2008, 16:54

danke schon mal für die antworten!
@mkallas: das problem bei nem ping ist, dass zwischen den laufzeiten der pings kurze verbindungsabbrüche zustande kommen können ohne dass ein ping das mitbekommt. der ping arbeitet eher nach dem fire and forget prinzip. er schiesst und es kommt halt entweder was zurück oder net. osi layer technisch arbeitet der ja auf ner anderen schiene als die auf der n tcp socket aufsetzt. deswegen bekomm ich da nur ne verlässliche antwort wenn ich ein socket aufmache und das dann iwann wegreisst - dann kann ich sagen: verbindung tot. (ich hab ein "ping -t 'zielhost' >> erg.txt" für nen tag laufen lassen, der brachte zwar schon das ergebnis, dass manche der pakete nicht durchkommen, aber das kann andere gründe haben. wichtig ist, rauszufinden ob eine bestehende(!) verbindung abkackt - neue verbindungen laufen auf grund von lasten oder anderen schweinereien die im netz laufen können(keine ahnung was alles) immer gefahr nicht "established" werden zu können - ich tendier da in richtung QoS von dem ich allerdings nicht weiss ob in dem netz sowas eingerichtet ist)

@ice2k3: den timeout den ich damit setzen würde bewirkt nur, dass wenn das socket noch keinen connect hatte, quasi wenn zwischen diesen beiden zeilen code

Code: Alles auswählen

socket.settimeout(5)
s.listen(1)
############### wenn nach 5 sekunden keiner coneccted gibts n timeout
conn, addr = s.accept() 
also ab dem listen bis zum accept für x sekunden nichts passiert, ich n timeout err geschmissen bekomm.
mein problem ist, dass ich die verbindung während das ding schon fleißig sendet unterbreche und dass dann erst nach 8 sek mitbekomm.
mach doch einfach mal den test - start die beiden skripte zieh das netzwerkkabel und zähl die sekunden bis es heisst 'Connection lost'. und genau diese zeit möchte ich auf einen möglichst geringen wert einstellen.
quasi : nw-kabel gezogen -> mit x ms zeitverzögerung: 'Connection lost'

was ich im internet grad noch gefunden habe is n codeschnipsel der das timeoutverhalten eines sockets verändert mit einer vorgegeben struktur. für mich ist leider nicht ganz ersichtlich wie ich diese struktur in python so umbiegen soll dass ichs mit nem ioctl vom socket auf ein solches anwenden kann.

Quelle: http://www.winsocketdotnetworkprogrammi ... ctl7f.html

Code: Alles auswählen

    // Set the keepalive values

    alive.onoff = TRUE;

    alive.keepalivetime = 7200000;

    alive.keepaliveinterval = 6000;

 

    if (WSAIoctl(s, SIO_KEEPALIVE_VALS, &alive, sizeof(alive), NULL, 0, &dwBytesRet, NULL, NULL) == SOCKET_ERROR)

    {

        printf("WSAIotcl(SIO_KEEPALIVE_VALS) failed with error code %d\n", WSAGetLastError());

        return -1;

    }

    else

        printf("WSAIotcl(SIO_KEEPALIVE_VALS) is working!\n");
Antworten