LINUX.ORG.RU

python - обрыв связи


0

0

Подскажите пожалуйста, как узнать об обрыве связи?

Простейший пример: есть  сервер и клиент на  питоне (TCP):
###############################
from  socket import *

s=socket( AF_INET, SOCK_STREAM)

s.connect(('10.1.1.80', 5001))

while 1:

   data = s.recv(256)

   print data

   if not data:

      print "close"

      s.close()

      break
############################## 

если сервер закрывает сокет, то все хорошо, печатается "close" и сокет  клиента закрывается, а вот если оборвать связь, или например, перезагрузить vmware, то клиент так и остается висеть

единственное , что пришло в голову - сделать сокет неблокирующим , но так как данные могут приходить через  произвольный момент времени, то тайм-аут придется сделать большим. А об обрыве связи мне надо узнать сразу, как быть?  
     
Заранее спасибо =)

>а вот если оборвать связь,

keepalive настраивать. Тогда через какое-то время само закроется.

DonkeyHot ★★★★★
()
Ответ на: комментарий от DonkeyHot

from  socket import *
s=socket( AF_INET, SOCK_STREAM)
s.setsockopt(SOL_SOCKET, SO_KEEPALIVE, 1)
s.connect(('10.1.1.80', 5001))
while 1:
         try:
             data = s.recv(1000)
             print data
             if not data:
                 print "close"
                 s.close()
                 break
             
         except error :
             print "server terminated"
             s.close()

Ничего не происходит уже минут 10..
А как можно настроить, кроме установки флага?
И собственно, его выставить только на стороне клиента или на стороне сервера тоже?

cavia_porcellus ★★★★
() автор топика
Ответ на: комментарий от cavia_porcellus

> нее, так не ловит, просто зависает в recv

на сервер смотреть надо. потому что при всякой фигне с сервером, на клиенте должен возникать exception "error: connection reset by peer"

ananas ★★★★★
()
Ответ на: комментарий от ananas

server.py:

#! /usr/bin/python

from SocketServer import *
import time

class Handler (BaseRequestHandler):
    def handle (self):
        for i in range(1000):
            self.request.send('echo %d\n' % i)
            time.sleep(2)


s = TCPServer(('127.0.0.1', 5001), Handler)
s.serve_forever()

client.py

#!/usr/bin/python

from socket import *

s=socket(AF_INET, SOCK_STREAM)

s.connect(('127.0.0.1', 5001))

while 1:
    try:
        data = s.recv(200)
        print data
    except:
        pass
    if not data:
        print "close"
        s.close()
        break

при обрубании сервера по ctrl+c клиент вполне себе нормально закрывается.

ananas ★★★★★
()
Ответ на: комментарий от ananas

по ctrl-c, то да =) 
а вот так?
####server############
from  socket import *
from sys import exit
s=socket(AF_INET, SOCK_STREAM)
s.bind(('localhost', 23334))
s.listen(1)
i=0
while 1:
     n, a =s.accept()
     print n, a
     while 1:
         i=i+100
         n.send(str(i))
         print i
         if i>1000:
            exit()
     print "closed"

cavia_porcellus ★★★★
() автор топика
Ответ на: комментарий от cavia_porcellus

>Ничего не происходит уже минут 10..

Умолчания обычно такие. Часа через 2 (TCP_KEEPIDLE) бездействия он пошлет первый пакет. И будет их cлать штук 10(TCP_KEEPCNT) раз в минуту(TCP_KEEPINTVL). Вот после этого...

Как ни странно - man tcp:-)

DonkeyHot ★★★★★
()
Ответ на: комментарий от cavia_porcellus

а так вообще все в порядке. в клиенте даже исключения не возникает

ananas ★★★★★
()
Ответ на: комментарий от DonkeyHot

проблема тут, скорее всего в том, что остается слушающий сокет при падении сервера.

netstat -l -t после обрыва что показывает?

ananas ★★★★★
()
Ответ на: комментарий от ananas

[root@marinus root]# netstat -a | grep 5001
tcp        0      0 localhost.localdom:5001 *:*                     LISTEN
tcp        0      0 localhost.localdom:5001 localhost.localdo:45381 ESTABLISHED
tcp        0      0 localhost.localdo:45381 localhost.localdom:5001 ESTABLISHED

Так вот , проблема по всей видимости в том, что клиент уверен, что сервер жив-здоров, а это не так..

cavia_porcellus ★★★★
() автор топика
Ответ на: комментарий от DonkeyHot

> Как ни странно - man tcp:-) 
вот такой параметр, я так понимаю - время бездействия (было 7200) 

[root@marinus root]# sysctl -w net.ipv4.tcp_keepalive_time=2

И все равно висит

cavia_porcellus ★★★★
() автор топика
Ответ на: комментарий от cavia_porcellus

netstat -p -l -t и смотреть, какой процесс держит сокет

ananas ★★★★★
()
Ответ на: комментарий от DonkeyHot

Прочитала у Стивенса, что значение этого параметра - минимум 2 часа =( Остальные оставила прежними. Возникла идея - открыть еще одно соединение, по которому клиент с сервером просто будут обмениватся тестовыми пакетиками - нет больше 5 минут -> обрыв связи... Хотя , наверно, есть более элегантный метод

cavia_porcellus ★★★★
() автор топика
Ответ на: комментарий от cavia_porcellus

>Прочитала у Стивенса, что значение этого параметра - минимум 2 часа

Я в Tru64 лично ставил 15 минут.

DonkeyHot ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.