在Python asyncio中检测套接字EOF

时间:2015-11-19 00:14:02

标签: python sockets 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协议中关闭连接?

2 个答案:

答案 0 :(得分:1)

  

当我在nc中键入Ctrl-D时,strace会立即显示套接字已关闭。

在我的系统w / gnu-netcat上,我必须使用netcat选项运行-c,以便在Ctrl-D上关闭套接字。您的脚本按预期工作。

nc6 -x做同样的事情,关闭eof上的套接字,而不只是stdin

答案 1 :(得分:-1)

看来你必须引发一个异常来结束循环。

以下是我的想法:

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)