twisted:在写入transp之前测试连接是否存在

2024-09-29 23:27:30 发布

您现在位置:Python中文网/ 问答频道 /正文

在执行transport.write()之前,是否有可能测试连接是否仍然存在?在

我修改了simpleserv/simpleclient示例,以便每隔5秒发送一条消息(写入Protocol.transport)。连接是持久的。在

断开wifi连接时,它仍然会写入传输(当然消息不会到达另一端),但不会抛出任何错误。 当再次启用wifi时,消息正在被传递,但是下一次发送消息的尝试失败(并且调用了Protocol.connectionLost)。在

这里又是按时间顺序发生的事情:

  1. 发送消息建立连接,消息即被传递。在
  2. 禁用wifi
  3. 发送消息写入transport,不会引发错误,消息不会到达
  4. 启用wifi
  5. 消息已发送到3。到达
  6. 发送消息会导致Protocol.connectionLost调用

最好在执行步骤6之前知道我是否可以写入传输。有什么办法吗?在

服务器

# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.


from twisted.internet import reactor, protocol


class Echo(protocol.Protocol):
    """This is just about the simplest possible protocol"""

    def dataReceived(self, data):
        "As soon as any data is received, write it back."
        print
        print data
        self.transport.write(data)

def main():
    """This runs the protocol on port 8000"""
    factory = protocol.ServerFactory()
    factory.protocol = Echo
    reactor.listenTCP(8000,factory)
    reactor.run()

# this only runs if the module was *not* imported
if __name__ == '__main__':
    main()

客户:

^{pr2}$

Tags: theecho消息datamainfactory错误this
1条回答
网友
1楼 · 发布于 2024-09-29 23:27:30

Protocol.connectionLost是知道连接何时不再存在的唯一方法。当已知连接不再存在时,也在最早的时间调用它。在

很明显,断开网络适配器(例如,关闭wifi卡)会断开连接-至少,如果您不关闭它,或者在重新打开时配置不同。但对于您平台的TCP实现来说,这并不明显。在

由于网络通信不是即时的,任何单个数据包都可能因正常(非致命)原因而丢失,TCP包括各种超时和重试。当您断开网络适配器的连接时,这些数据包将无法再被传递,但平台不知道这种情况将持续最长的TCP超时时间。所以当你关闭wifi时,你的TCP连接不会关闭。它会挂起并开始重试发送并等待确认。在

在某些时候,超时和重试都会过期,并且连接确实会关闭(虽然TCP的工作方式意味着如果有没有数据等待发送,那么实际上没有超时,“死”连接将永远存在;解决这一问题是TCP“keepalive”功能存在的原因)。由于连接的两个侧都有超时,这一点稍微复杂一些。如果您在第六步中完成写操作后就关闭了连接(而且不会很快关闭),那么原因可能是一个“reset”(RST)包。在

在连接另一端的超时过期后,将发生重置,并在连接仍处于打开状态时关闭连接。现在,当您的一方为这个TCP连接发送一个包时,另一方将无法识别它所属的TCP连接(因为另一方认为连接已不存在),并用重置消息进行回复。这会告诉原始发送方没有这种连接。原始发送方对此的反应是关闭其连接的一侧(因为双边连接的一侧本身并不是很有用)。这大概是在应用程序中调用Protocol.connectionLost时发生的。在

所有这些基本上就是TCP的工作原理。如果超时行为不适合您的应用程序,那么您有几个选项。您可以启用TCP keepalive(这通常没有帮助,默认情况下,TCP keepalive会引入长达数小时的超时,尽管您可以在大多数平台上对此进行优化),或者您可以构建应用程序级别的keepalive特性。这只是一些额外的流量,你的协议生成,然后期望一个响应。你可以建立自己的超时(3秒内没有响应?关闭连接并建立一个新的)在此基础上,或者仅仅依靠它来触发一个稍快(约2分钟)的TCP超时。更快超时的缺点是,虚假的网络问题可能会导致您在不需要时关闭连接。在

相关问题 更多 >

    热门问题