У меня есть простой сервер, подобный этому:
#!/usr/bin/env python2
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('localhost', 50000))
server.listen(5)
# Set TCP Keepalive
server.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
server.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 1)
server.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 3)
server.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 5)
connection, client_address = server.accept()
while True:
try:
data = connection.recv(1024)
except socket.error:
print "%s dropped out" % (connection.getpeername(),)
break
if data:
print "%s: %s" % (connection.getpeername(), data)
else:
print "%s disconnected" % (connection.getpeername(),)
break
Я использую TCP Keepalive, чтобы выяснить, исчезает ли клиент (а не правильно отключается).
Проблема, с которой я сталкиваюсьв том, что когда клиент действительно исчезает, и я ловлю исключение socket.error, моя инструкция print пытается выяснить, какой клиент отключен, с помощью connection.getpeername (), который больше не работает.Он генерирует исключение
socket.error: [Errno 107] Transport endpoint is not connected
.
В этом простом примере есть только один клиент, который может подключаться одновременно, но с более сложным кодом, который обрабатывает несколько клиентов одновременно, онможет быть полезно узнать, какой клиент отключился.
После того, как сокет отсоединился, нет ли способа узнать, к какой конечной точке он был ранее подключен?Почему объект connection
не сохраняет информацию об IP-адресе / порте клиента в connection.getpeername()
даже после отключения клиента?Это потому, что объект connection
потенциально можно использовать повторно?
Как я могу заставить мой код работать на самом деле и распечатать, какой клиент пропал?Нужно ли сохранять вывод connection.getpeername()
в переменной, чтобы я мог вспомнить его позже?Это означало бы, что если у меня несколько клиентов, мне нужно было бы хранить значение connection.getpeername()
для каждого клиента в списке?
Я знаю, что использование socket
- довольно низкий уровень, и я уверен, чтов действительности проще было бы использовать SocketServer.TCPServer
- я просто пытаюсь понять, что такое низкоуровневая сеть.