@termitik

Как проверить на подключение клиента по socket python?

Всем привет!
Делаю сокет сервер на python.
Свою программу скидывать не буду, так как лишнего много, возьму простейшую программу.
import socket

sock = socket.socket()
sock.bind(('', 9090))
sock.listen(1)
conn, addr = sock.accept()

print 'connected:', addr

while True:
    data = conn.recv(1024)
    conn.send(data.upper())


Если я хочу установить сокет который длится бесконечно, при чем сервер как слушает, так и говорит.
Непонятки в том, что клиент может оборваться без предварительного сообщения. Как тогда отключить клиента от сокета на стороне сервера. Ведь если клиент отключился, а я не удалил его с сервера, то когда он будет подключаться снова conn, addr = sock.accept() выполняться не будет и программа зависнет. Как проверять, активен ли socket клиент или нет
  • Вопрос задан
  • 4911 просмотров
Пригласить эксперта
Ответы на вопрос 3
Вы уверены, что зависнет? Вроде бы не должно быть таких ограничений - 1 клиент 1 сокет.

Можно регулярно пинговать клиента через сокет и, если он не ответил, закрывать соединение. Еще стоит выставить socket.timeout для стединений.
Ответ написан
@mir546
creator
При каждой отправке пакетов обновлять переменную
lastpacket = time.time() # дата крайней отправки пакета

Далее в нужный момент делаем проверку
if time.time() - lastpacket > 30: # отправки не было более 30 сек.
  self.log('connection timed out') # значит соединение можно считать разорванным

Параллельно с этим(в отдельном потоке) каждые, например, 10 секунд отправляем Keep Alive:
try:
  sock.send("\x05")  # отправляем любые данные
except:
  self.log('connection timed out') # соединение разорвано
time.sleep(10)

Рабочее решение.
Если есть решение лучше - скажите об этом.
Ответ написан
Комментировать
@logos7
Непонятки в том, что клиент может оборваться без предварительного сообщения. Как тогда отключить клиента от сокета на стороне сервера.

Клиент от сокета отключится сам, после того как вы закроете коннект conn.close(). Если клиент отключился самостоятельно то socet выдаст исключение [WinError 10054] Удаленный хост принудительно разорвал существующее подключение. А если отвалился без предупреждений, то блокирующий метод conn.recv(1024) вернет 0 байт. Этот метод либо разблокируется по таймауту, который можно предварительно задать или по получении полезных данных или получении данных b'' длиной ноль байт, что означает, что клиент отвалился от сокета.

Ведь если клиент отключился, а я не удалил его с сервера, то когда он будет подключаться снова conn, addr = sock.accept() выполняться не будет и программа зависнет.
Да будет подключаться если ему надо и ничего не зависнет.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы