[英]UDP flow control with Python Twisted
我有一个继承自twisted.internet.protocol.DatagramProtocol
类的类。 在我的startProtocol()
实现中,我调用了startWriting()
,这样每次我可以在不阻塞的情况下写入套接字时会通知套接字。 两个问题:
startWriting()
方法? 哎呀。 我想我可能已经在另一个帖子中回答了你的问题,并让你相信Twisted中的UDP流控制支持比实际上更强大。 不过,你可以得到你需要做的事......
不幸的是,Twisted中的UDP协议不会受到可写性的监控,前提是UDP总是会失败,因此它永远不会引发EWOULDBLOCK
。 (实际上,它确实有时, 这是Twisted中的一个错误 ,我在回答这个问题时才重新发现。只有当Twisted以比本地线速更快的速度发送UDP时才会发生这种情况,这需要非常快的应用程序和非常快速的应用程序。慢网络。)
作为一种解决方法,您的应用程序可以简单地捕获EWOULDBLOCK
。 对于任何其他协议,此类解决方案可能构成严重问题,但在UDP的情况下,您必须准备丢失任何传出数据包,因此无论如何您都需要带内控制流机制。
如果你想变得非常花哨,你可以编写自己的替代udp.Port
(通过自己实现IFileDescriptor
)而不是编写UDP协议,并覆盖doRead
和doWrite
(当底层套接字分别是可读写时调用) 。 这将为您提供完美的写入级别流量控制,但可能不是必需的,因为UDP有时会丢弃您的数据包,并且在网络上无法正确处理“ICMP源淬火”消息(哑巴防火墙配置为阻止ICMP将阻止),丢弃的数据包是您唯一的流控制信息源。 我并不是说你不应该在Twisted中修复这个错误,但UDP世界中的这个生活事实可能是没有人为此烦恼的原因。
由于本答案第1部分中描述的限制,UDP传输没有有用的startWriting
方法。
但是, startWriting
/ stopWriting
实际上并不是限制传出UDP带宽的正确方法。
在通过适当的调度机制调度所述调用之后,只需在适当的时间调用self.transport.write(...)
。 例如, LoopingCall
被设计为以适当的间隔调用用于传输声音样本的RTP媒体流的UDP发送。 但您也可以直接计算自己的延迟并使用callLater 。 在任何情况下,如果您需要重新传输排队等待通过UDP传输的传出数据,您可能需要保留某种队列机制,所以只需弹出
如果你需要进行入站流量控制,UDP传输仍然可以很好地支持,使用stopReading
和startReading
。
希望这个答案很有帮助,如果我之前误解了Twisted在这方面的能力,那就很抱歉!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.