【问题标题】:Handling Python sockets处理 Python 套接字
【发布时间】:2018-11-20 01:01:51
【问题描述】:

首先,我得到了以下代码......有效。显然。

while not self.socket_connected:
    try:
        client_socket.connect((self.hostname, self.port))
        self.socket_connected = True
    except:
        sleep(0.5)
        pass

while self.socket_connected:
    message = client_socket.recv(4096)
    if(message == b''):
        client_socket.close()
        self.socket_connected = False
        break

    #...do stuff

我说“显然”是因为我正在阅读关于应该如何在 Python 中实现套接字的相互冲突的资料。

首先,您获得了herehere 等信息,这会让您相信空缓冲区是断开连接的套接字。这一定是我首先阅读的内容(上面的代码此时已经有几个月的历史了,也是我第一次认真尝试 Python 中的套接字)。

不过,还有 this 的帖子似乎更明智一些。也就是说,如果缓冲区是空的,这仅仅意味着你现在已经阅读了所有可用的内容。有点像我最初是如何理解 TCP 工作的。也许我错过了,但在文档中甚至是 mentioned 吗?

无论如何...我意识到我的代码是,每次缓冲区为空时,我都会删除客户端套接字并重新连接以读取新信息。这显然不理想,我想改变它。

在 C 中,如果 recv 返回零,则缓冲区为空。如果它返回

编辑: 多一点上下文 - 我已将此处接收到的消息的前五个字节编码为整个消息的大小,因此我将能够进行测试用于内部“完成”,前提是我可以区分空缓冲区和丢弃的套接字。

编辑 2: 我要特别问的是如何检查 Python 套接字是否有空缓冲区和断开的连接。当然,两者的处理方式应该不同,而且我需要通过多次recv() 调用来确保我收到完整的消息。

【问题讨论】:

    标签: python linux python-3.x


    【解决方案1】:

    默认情况下,socket.recv 是一个阻塞调用,它会暂停线程,直到它在缓冲区中接收到一些东西,然后它会返回整个缓冲区。

    当一个套接字断开连接时,缓冲区将变为 b'' 不为空,因此它返回 b''。

    调用 .recv 时没有数据的非阻塞套接字将返回套接字异常。

    所以要回答我认为的问题,默认情况下,socket.recv 将在客户端断开连接时返回 b''。

    edit:要查看套接字是否为空,您可以禁用阻塞,然后在缓冲区为空时捕获通过调用 recv 引发的异常。

    或者使用带有套接字的 select 模块将您的套接字分类为 3 个列表,准备读取、准备写入和带有异常的套接字。

    https://docs.python.org/3/library/select.html#select.select

    【讨论】:

    • 那么测试b'' 是否为断开连接的套接字,msg == None 或其他什么是否为空缓冲区?我正在尝试对两者进行测试,以便我可以解释部分消息以及丢失的套接字。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-14
    • 1970-01-01
    • 1970-01-01
    • 2017-01-31
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    相关资源
    最近更新 更多