[英]Detect socket EOF in Python asyncio
I'm writing a simple socket server that receives some messages. 我正在编写一个接收一些消息的简单套接字服务器。
The only challenge left: If the client sends EOF, the connection does not close or the EOF is detected. 唯一的挑战是:如果客户端发送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()
I'm connecting there with strace nc localhost 1337
. 我用
strace nc localhost 1337
连接那里。 When I send lines to nc
, they are receieved of course. 当我向
nc
发送线路时,他们当然会收到。 When I type Ctrl-D in nc
, strace
instantly reveals that socket was closed. 当我在
nc
键入Ctrl-D时, strace
立即显示套接字已关闭。
But the python script does not notice the EOF and keeps the connection open. 但python脚本没有注意到EOF并保持连接打开。 When I kill
nc
, then the connection closes. 当我杀死
nc
,连接关闭。
What can I do to close the connection in the asyncio protocol as soon as nc
sends the EOF? 如果
nc
发送EOF,我该怎么做才能在asyncio协议中关闭连接?
When I type Ctrl-D in nc, strace instantly reveals that socket was closed.
当我在nc中键入Ctrl-D时,strace会立即显示套接字已关闭。
On my system w/ gnu-netcat
, I have to run netcat
with the -c
option for the socket to be shutdown on Ctrl-D. 在我的系统w /
gnu-netcat
,我必须使用-c
选项运行netcat
,以便在Ctrl-D上关闭套接字。 Your script works as expected. 您的脚本按预期工作。
nc6 -x
does the same thing, close the socket on eof, not just stdin
. nc6 -x
做同样的事情,关闭eof上的套接字,而不仅仅是stdin
。
It appears you have to raise an exception to end the loop. 看来你必须引发异常才能结束循环。
Here is what I have come up with: 以下是我的想法:
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.