在 Python asyncio 中检测套接字 EOF
Detect socket EOF in Python asyncio
我正在编写一个简单的套接字服务器来接收一些消息。
剩下的唯一挑战:如果客户端发送 EOF,连接不会关闭或检测到 EOF。
#!/usr/bin/env python
import asyncio
class Protocol(asyncio.Protocol):
def connection_made(self, transport):
self.peername = transport.get_extra_info("peername")
print("Connection from %s" % (self.peername,))
self.transport = transport
def eof_received(self):
print("end of stream!")
self.close()
def close(self):
self.transport.close()
def connection_lost(self, exc):
print("Connection lost with %s" % (self.peername,))
def data_received(self, data):
print("received: %s" % data)
def main():
loop = asyncio.get_event_loop()
coro = loop.create_server(Protocol, "localhost", 1337)
server = loop.run_until_complete(coro)
print("Listening on %s..." % (server.sockets[0].getsockname(),))
try:
loop.run_forever()
except KeyboardInterrupt:
print("exiting...")
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()
if __name__ == "__main__":
main()
我正在连接 strace nc localhost 1337
。
当我向 nc
发送线路时,他们当然会收到。
当我在 nc
中键入 Ctrl-D 时,strace
立即显示套接字已关闭。
但是 python 脚本没有注意到 EOF 并保持连接打开。当我杀死 nc
时,连接将关闭。
如何在 nc
发送 EOF 后立即关闭 asyncio 协议中的连接?
看来您必须引发异常才能结束循环。
这是我想出的:
class Protocol(asyncio.Protocol):
def connection_made(self, transport):
self.peername = transport.get_extra_info("peername")
print("Connection from %s" % (self.peername,))
self.transport = transport
def eof_received(self):
print("end of stream!")
def close(self):
raise KeyboardInterrupt
def connection_lost(self, exc):
print("Connection lost with %s" % (self.peername,))
self.close()
def data_received(self, data):
print("received: %s" % data)
When I type Ctrl-D in nc, strace instantly reveals that socket was closed.
在我的系统上 gnu-netcat
,我必须 运行 netcat
和 -c
选项才能在 Ctrl-D 上关闭套接字。您的脚本按预期工作。
nc6 -x
做同样的事情,关闭 eof 上的套接字,而不仅仅是 stdin
.
我正在编写一个简单的套接字服务器来接收一些消息。
剩下的唯一挑战:如果客户端发送 EOF,连接不会关闭或检测到 EOF。
#!/usr/bin/env python
import asyncio
class Protocol(asyncio.Protocol):
def connection_made(self, transport):
self.peername = transport.get_extra_info("peername")
print("Connection from %s" % (self.peername,))
self.transport = transport
def eof_received(self):
print("end of stream!")
self.close()
def close(self):
self.transport.close()
def connection_lost(self, exc):
print("Connection lost with %s" % (self.peername,))
def data_received(self, data):
print("received: %s" % data)
def main():
loop = asyncio.get_event_loop()
coro = loop.create_server(Protocol, "localhost", 1337)
server = loop.run_until_complete(coro)
print("Listening on %s..." % (server.sockets[0].getsockname(),))
try:
loop.run_forever()
except KeyboardInterrupt:
print("exiting...")
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()
if __name__ == "__main__":
main()
我正在连接 strace nc localhost 1337
。
当我向 nc
发送线路时,他们当然会收到。
当我在 nc
中键入 Ctrl-D 时,strace
立即显示套接字已关闭。
但是 python 脚本没有注意到 EOF 并保持连接打开。当我杀死 nc
时,连接将关闭。
如何在 nc
发送 EOF 后立即关闭 asyncio 协议中的连接?
看来您必须引发异常才能结束循环。
这是我想出的:
class Protocol(asyncio.Protocol):
def connection_made(self, transport):
self.peername = transport.get_extra_info("peername")
print("Connection from %s" % (self.peername,))
self.transport = transport
def eof_received(self):
print("end of stream!")
def close(self):
raise KeyboardInterrupt
def connection_lost(self, exc):
print("Connection lost with %s" % (self.peername,))
self.close()
def data_received(self, data):
print("received: %s" % data)
When I type Ctrl-D in nc, strace instantly reveals that socket was closed.
在我的系统上 gnu-netcat
,我必须 运行 netcat
和 -c
选项才能在 Ctrl-D 上关闭套接字。您的脚本按预期工作。
nc6 -x
做同样的事情,关闭 eof 上的套接字,而不仅仅是 stdin
.