[英]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.