server/client TCP

0

Witam,

Założenia:

  • client TCP
  • server TCP

W jaki sposób sprawdzać czy połączenie client server zostało utracone?
Client TCP połączył się z serverem TCP, wymieniając dane.
Program server tcp zawiesił się, zakończył działanie, a client tcp dalej wysyła dane, nie został poinformowany o utracie kontaktu z serwerem. W jaki sposób client Tcp może się dowiedzieć, że połączenie zostało utracone.

1

Zakładając, że łączysz się po TCP korzystając z socketów to: https://stackoverflow.com/questions/667640/how-to-tell-if-a-connection-is-dead-in-python

0

Jeśli server tcp zakończy działanie, to twój socket w system operacyjnym nie dostanie potwierdzeń odbioru transmisji na warstwie tcp, więc zgłosi błąd do warstwy wyżej, gdzie jest intepreter pythona, wykonujący kod twojego programu klienckiego, który wykonuje write() (w postaci write, send, sendall, itp), i tenże write() zostanie przerwany przez wyjątek w pythonie, który ty złapiesz parę linijek niżej używając "except socket.ConnectionResetError as e:".

0
bdwn napisał(a):

Jeśli server tcp zakończy działanie, to twój socket w system operacyjnym nie dostanie potwierdzeń odbioru transmisji na warstwie tcp, więc zgłosi błąd do warstwy wyżej, gdzie jest intepreter pythona, wykonujący kod twojego programu klienckiego, który wykonuje write() (w postaci write, send, sendall, itp), i tenże write() zostanie przerwany przez wyjątek w pythonie, który ty złapiesz parę linijek niżej używając "except socket.ConnectionResetError as e:".

To nie takie proste. ConnectionResetError jest tylko jeżeli dostał RST od hosta serwera (i może po FIN od serwera, ale głowy nie daję). Jeżeli host, a właściwie jego kernel, był na tyle miły, że zobaczył proces, który się wywalił, to może i wyśle RST na tym połączeniu.

Ale jeżeli ktoś odłączył tą maszynę od sieci lub sama maszyna padła fizycznie, to można zapomnieć o RST. Wtedy jedyna nadzieja w timeoutach TCP. Będziesz wisiał dopóki nie przekroczysz tiemeoutu tcp (https://docs.python.org/3/howto/sockets.html#when-sockets-die). Strategia dla timeoutu z kolei jest zależna od konfiguracji stosu sieciowego. Dla Linuxa polecam zapoznać się z https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt . Ale jeżeli nic nie wysyłałeś, jedynie utrzymywałeś połączenie, to timeout w ogóle nie zostanie złapany.

Inną opcją jest skorzystanie z opcji keepalive ( https://stackoverflow.com/questions/12248132/how-to-change-tcp-keepalive-timer-using-python-script ) albo timeoutów na operacjach blokujących.

0

Tak, oczywiście masz rację. Sprowadziłem to do najprostszego przypadku, i pominąłem temat timeoutów, blocking/non-blocking, itd. Wprawdzie pytanie wspomina o scenariuszu "serwer zawiesił się", jednak założyłem brak warunku "== połączenie nie zostało utracone jeśli serwer 'odwiesi się' w przedziale czasowym X".
Przy okazji - sytuację "serwer po prostu zniknął" chyba najłatwiej jest zasymulować poprzez drop pakietów, "block drop" (https://www.freebsd.org/doc/handbook/firewalls-pf.html -> "30.3.3.7. Network Hygiene")

1 użytkowników online, w tym zalogowanych: 0, gości: 1