【发布时间】:2018-12-09 18:50:09
【问题描述】:
我有一个这样的简单服务器:
#!/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 异常时,我的打印语句试图通过使用 connection.getpeername() 来确定哪个客户端断开连接,这不再有效。它抛出一个
socket.error: [Errno 107] Transport endpoint is not connected
异常。
在这个简单的示例中,任何时候只有一个客户端可以连接,但是对于同时处理多个客户端的更复杂的代码,了解哪个客户端退出可能会很有用。
一旦套接字断开连接,是否无法知道它之前连接到的端点?
为什么connection对象没有在connection.getpeername()中保留客户端的IP/端口信息,
即使在客户端断开连接后?这是因为connection 对象可能是可重用的吗?
我怎样才能让我的代码真正起作用,并打印出哪个客户端退出了?我是否需要将connection.getpeername() 的输出存储在一个变量中,以便稍后调用?这意味着如果我有多个
客户,我需要将每个客户的 connection.getpeername() 值存储在列表中吗?
我知道使用socket 是相当低级的,我很确定使用SocketServer.TCPServer 会更容易 - 我只是想了解所涉及的低级网络。
【问题讨论】:
标签: python sockets networking