【问题标题】:The first is disconnected only when second client connects in twisted仅当第二个客户端以双绞线连接时,第一个才断开连接
【发布时间】:2014-06-29 01:21:32
【问题描述】:

我有以下监听客户端的扭曲服务器代码

class Echo(LineReceiver):

    def connectionMade(self):
        self.factory.clients.append(self)
        self.setRawMode()
        self._peer = self.transport.getPeer()
        timerClass(self)

    def connectionLost(self, reason):
        self.factory.clients.remove(self)
        print 'Lost connection from', self._peer

def why(self):
    print str(self._peer) + "we"
    self.transport.abortConnection()

def timerClass(self):
    t = Timer(2.0, lambda:why(self))
    t.start()

根据我的代码,客户端应在连接到服务器后 2 秒后断开连接。但是客户端在 2 秒后没有断开连接,它在第二个客户端连接到服务器后断开连接。为什么会这样,我想不通。

【问题讨论】:

  • 以后发sscce.org,这样人们就不用猜测你的程序做了什么。

标签: python-2.7 twisted


【解决方案1】:

让我眼前一亮的是你的Timer 电话,这是从哪里来的?是timeit.Timer

它突然出现在我身上的原因是,如果你阻塞反应堆,Twisted 的行为就会变得很糟糕,除非我弄错了,否则调用是阻塞睡眠。 (我还发现了一些对线程 timer 调用的引用,这也可能导致扭曲的问题,因为大部分扭曲不是线程安全的,因此以下答案仍然适用)

通常在 Twisted 中,您希望对这种应用程序使用 reactor.callLater 延迟方法。见:http://twistedmatrix.com/documents/current/core/howto/time.html

我猜你的代码并不是真的在等待下一个连接,而是睡眠会阻塞下一个连接,直到计时器用完,此时你会看到你的第二个连接连接并且你的第一个连接死亡。

尝试使用reactor.callLater 代替您的 Timer 呼叫,看看是否能解决您的问题。如果不使用更多代码/测试示例更新您的问题

更新(...评论指出这个问题是threading 而不是timeit

鉴于 Twisted 的许多部分都不是线程安全的(“不安全”意味着 任何事情 都可能发生 - 行为不可预测),以下只是猜测,但我认为这是对您看到的奇怪行为的合理解释:

  1. 您的reactor.run 设置了一个select/epoll/which-ever-event-call-style-of-loop,仅注册了您的通信文件描述符以唤醒事件调用并进入睡眠状态。
  2. 你的第一个连接进来了,它瞬间唤醒了 twisted 以服务连接,你的 timerClass 正在运行,但 twisted 重新进入睡眠状态,幸福地没有意识到线程。这意味着:
  3. 当您的线程睡眠完成并运行self.transport.abortConnection 时,设置了一些打算关闭连接的变量,但在 Twisted 唤醒之前无法执行这些变量背后的工作(......我的具体细节可能特别错误在这里,我还没有挖掘abortConnection 代码库以确保这是该调用的真实情况)
  4. 在 Twisted 重新唤醒之前,一切都被卡住了,但这只会发生在一个事件中,例如:
  5. 您建立了第二个连接,这会唤醒 Twisted 事件调用
  6. 随着 Twisted 再次唤醒,在线程调用中启动的 abortConnection 进程可以完成,杀死第一个连接。

对该理论的测试是让第一个连接在线程Timer 运行transport.abortConnection 之后发送数据。接收数据应该唤醒 Twisted,按照我的理论,应该让 transport.abortConnection 完成而不需要第二次连接。

话虽如此,修复方法是一样的。切换到 Twisted 的 reactor.callLater,它将一个定时器直接注册到 Twisted 的事件睡眠中。

如果您对 Twisted 与线程的更长分解感兴趣,请参阅我在 How to run a program and also execute code... 上的回答

【讨论】:

  • 感谢您的精彩解释。
猜你喜欢
  • 2013-10-20
  • 1970-01-01
  • 2020-07-21
  • 1970-01-01
  • 1970-01-01
  • 2019-09-11
  • 2018-03-11
  • 2017-07-17
  • 2010-11-01
相关资源
最近更新 更多