3

クラスから継承するtwisted.internet.protocol.DatagramProtocolクラスがあります。私のstartProtocol()実装ではstartWriting()、を呼び出します。これにより、ブロックせずにソケットに書き込むことができるたびに、ソケットに通知が届きます。2つの質問:

  1. ソケットが書き込み可能になると、ツイストされたどのメソッドが呼び出されますか?
  2. startWriting()発信UDP帯域幅を特定のデータグラム/秒の量に制限するために特定の時間間隔で呼び出す必要がある場合、メソッドをどのように呼び出す必要がありますか?
4

1 に答える 1

2

おっとっと。別のスレッドであなたの質問に答えたので、Twisted での UDP フロー制御サポートは実際よりも少し堅牢であると思われるかもしれません。それでも、やりたいことはできる...

1. ソケットが書き込み可能になると、Twisted はどのメソッドを呼び出しますか?

残念ながら、Twisted の UDP プロトコルは、UDP は常に失敗する可能性があり、決してEWOULDBLOCK. (ただし、実際には時々発生します。これは Twisted のバグであり、この質問に回答しているときに再発見しました。これは、Twisted がローカル ワイヤ スピードよりも速い速度で UDP を送信している場合にのみ発生します。これには、非常に高速なアプリケーションと非常に高速なアプリケーションが必要です。ネットワークが遅い。)

回避策として、アプリケーションは単純に をキャッチできますEWOULDBLOCK。他のプロトコルの場合、この種の回避策は重大な問題を引き起こす可能性がありますが、UDP の場合は、発信パケットを失う準備をしておく必要があるため、とにかくインバンド制御フロー メカニズムが必要です。

レビュープロセスを通じてそのバグを取得するのを支援することも、常にオプションです.

本当に凝ったものにしたい場合は、UDP プロトコルを記述するのではなく、udp.Port(自分で実装することによって) 独自の代替案を記述し、および(基礎となるソケットがそれぞれ読み取り可能および書き込み可能であるときに呼び出される) をオーバーライドすることができます。これにより、完全な書き込みレベルのフロー制御が可能になりますが、UDP はパケットをドロップすることがあるため、おそらく必要ありません。また、「ICMP ソース クエンチ」メッセージを適切に処理できないネットワーク上では (これは、ダム ファイアウォールが設定されています)。ブロック ICMP はブロックするだけです)、ドロップされたパケットはあなたの唯一のものですIFileDescriptordoReaddoWriteフロー制御情報のソース。Twisted でこのバグを実際に修正するべきではないと言っているわけではありませんが、UDP の世界でのこの事実が、まだ誰も修正しようとしない理由の 1 つです。

2. 送信 UDP 帯域幅を特定のデータグラム/秒量に制限するために特定の時間間隔で呼び出す必要がある場合、startWriting() メソッドをどのように呼び出す必要がありますか?

この回答のパート 1 で説明されている制限により、UDP トランスポートには有用なstartWriting方法がありません。

ただし、とにかく発信 UDP 帯域幅を時間制限する正しい方法はstartWriting/ではありません。stopWriting

self.transport.write(...)適切なスケジューリング メカニズムを介してコールをスケジューリングした後、適切な時間に コールするだけです。LoopingCallたとえば、サウンド サンプルを送信するための適切な間隔で、RTP メディア ストリーミングの UDP 送信を呼び出すように設計されています。ただし、独自の遅延を計算してcallLaterを直接使用することもできます。いずれにせよ、UDP を介したトランスポートのためにキューに入れられた送信データの再送信を行う必要がある場合に備えて、何らかのキュー メカニズムを保持する必要がある可能性が高いため、ポップするだけです。

インバウンドフロー制御を行う必要がある場合、UDP トランスポートは と を使用してそれを適切にサポートしstopReadingますstartReading

この回答がお役に立てば幸いです。以前、この分野での Twisted の機能について誤解を招いていた場合は申し訳ありません!

于 2011-10-28T12:20:47.173 に答える