【问题标题】:Detect why a socket closed: FIN vs RST检测套接字关闭的原因:FIN vs RST
【发布时间】:2018-11-16 20:56:32
【问题描述】:

是否可以检测出 Python 中套接字关闭的原因,即对方是否发送了 FIN 或 RST?

我知道检测对方是否有发送 FIN 或 RST 的唯一方法是从套接字读取,如果你得到空(字节)字符串,那么我们收到了 FIN 或 RST。但是怎么知道是哪一个呢?

import asyncio
import socket

async def async_main(loop):

    server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM,
                                proto=socket.IPPROTO_TCP)
    server_sock.setblocking(False)
    server_sock.bind(('', 8080))
    server_sock.listen(socket.IPPROTO_TCP)

    loop = asyncio.get_event_loop()
    sock, adddress = await loop.sock_accept(server_sock)

    while True:
        data = await loop.sock_recv(sock, 1024)
        if data == b'':
            # Socket closed, but how?
            break
        print(data)

loop = asyncio.get_event_loop()
loop.run_until_complete(async_main(loop))

【问题讨论】:

  • 我希望在收到 FIN 时出现正常的 EOF 条件(data == b'')。如果您收到 RST,我希望会引发“对等连接重置”形式的异常。

标签: python python-3.x sockets tcp python-asyncio


【解决方案1】:

基于 James K Polk 的 comment,我认为这是正确的,您可以通过捕获适当的异常来区分 FINRST

    while True:
        is_rst = False
        try:
            data = await loop.sock_recv(sock, 1024)
        except IOError as e:
            if e.errno == errno.ECONNRESET:
                data = b''
                is_rst = True
            else:
               raise
        if data == b'':
            # Connection closed - use is_rst to distinguish
            # between RST and FIN
            break
        print(data)

【讨论】:

  • 谢谢,感谢@james-k-polk:我的假设完全错误。
猜你喜欢
  • 2013-12-10
  • 2010-09-27
  • 2013-02-17
  • 1970-01-01
  • 2011-02-06
  • 2014-10-21
  • 1970-01-01
  • 2012-10-14
  • 1970-01-01
相关资源
最近更新 更多