Twisted的Connection
类继承write
了abstract类的方法FileDescriptor
。如您在这里看到的,该类具有一个缓冲区,直到缓冲区的字节总数大于bufferSize
(class中的attribute FileDescriptor
)时,该缓冲区才会刷新。
对于我的特定需求,我想尽快将数据写入套接字,因此我想避免在传输的任何时候对它们进行缓冲。我已设置TCP_NODELAY
为套接字,但仍在Twisted的write
调用中缓冲数据。
因此,我解决此问题的FileDescriptor.doWrite
方法是调用方法,该方法将尝试在缓冲区中写入任何数据(请参阅参考资料)。我doWrite
总是打电话write
如下:
...
self.transport.write(data)
self.transport.doWrite()
...
解决方法似乎运行良好,但有时会出现以下错误:
self.transport.doWrite() # Flush twisted buffer
File "/usr/local/lib/python2.7/dist-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/internet/abstract.py", line 270, in doWrite
self.stopWriting()
File "/usr/local/lib/python2.7/dist-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/internet/abstract.py", line 429, in stopWriting
self.reactor.removeWriter(self)
File "/usr/local/lib/python2.7/dist-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/internet/epollreactor.py", line 344, in removeWriter
EPOLLOUT, EPOLLIN)
File "/usr/local/lib/python2.7/dist-packages/Twisted-14.0.2-py2.7-linux-x86_64.egg/twisted/internet/epollreactor.py", line 322, in _remove
primary.remove(fd)
KeyError: 11
问题在于doWrite
调用stopWriting
试图从中的writers列表中删除自身(Connection
对象)reactor
。出现异常是因为它无法在列表中找到该对象。
这很奇怪,因为write
应该在data
没有参数的情况下注册读者None
(我认为问题是数据有时是None
,所以我在存在数据的情况下包含了write
&doWrite
)。因此,我决定只捕获KeyError
异常并忽略它,如下所示:
...
if data:
self.transport.write(data)
try:
self.transport.doWrite()
except KeyError:
pass
...
但是,异常会不断弹出,甚至会关闭TCP连接。
我不知道现在在哪里以及为什么引发异常,我不知道doWrite
。另外,我不知道此骇客有何副作用。可能是我过度简化了Twisted的整个文件描述符范式(我还不太了解)。我也不知道这是否是实际的预期行为,在任何情况下,Twisted都不应该在从列表中删除该元素之前先检查该元素是否在作家列表中吗?
doWrite
不在那里给您打电话。它是运输和反应堆之间界面的一部分。它不是传输和协议之间接口的一部分。
FileDescriptor
在写入一定数量的字节之前,不缓冲写操作。它最多仅缓冲写操作,直到反应堆有机会再次运行为止。Twisted是一种协作式多任务系统。一次只发生一件事。如果正在发生的一件事是您的应用程序代码正在运行,那么反应堆将无法完成其工作(例如将字节写入文件描述符)。每件事都必须等待对方完成才能开始。
不管是什么导致您得出基于大小的写缓冲区的结论都是错误的。无论您要解决什么问题,解决方案都不会像这样。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句