2

簡単に言うと、Linux では、特定の TCP パケットに対して ACK メッセージが確実に受信されるようにするにはどうすればよいですか?

全文:

Asterisk/OpenH323 <-> Panasonic IP-GW16 の問題をデバッグしています。

H323 接続には、H225.0 と H245 の 2 つのセッションが含まれます。これらは、いくつかのデータが送信される 2 つの TCP セッションです。

Session 1それらを(H225.0の場合)および(H245の場合)と呼びましょうSession 2

Session 1には既知の TCP ポート番号 1720 があり、Session 2実行時にポートが選択されます。

制御フローは次のようになります。

  1. Panasonic は、Asterisk を呼び出します。これは、(TCP/1720) で Asterisk を開き、パナソニックがリッスンするを含むSession 1を介して SETUP メッセージを送信します。Session 1port 2
  2. アスタリスクは Panasonic に CALL PROCEEDING メッセージを送信します。Session 1
  3. パナソニックがリスニングを開始port 2
  4. Panasonic は で TCP ACK を送信しますSession 1
  5. Session 2アスタリスクは で TCPを開きますport 2

ステップ 2 と 3 の順序が重要ですport 2。Panasonic は、 で CALL PROCEEDING メッセージを受信しない限り、 をリッスンしませんstep 2

しかし、OpenH323 コードでstep 2は、step 5わずか数行しか離れていません。

そのため、接続sometimesはデバッグ モードでquite never機能し、リリースで機能します。

これは、パケット ダンプで明確に確認できます。一連の実験を行ったところ、52 件中 52 件で、step 5前に進むstep 4と接続に失敗しました。そうでない場合、接続は成功します。

の ACK を除いて、Panasonic から送信された他のメッセージはありませんstep 4。Asterisk が聞いていることを知る唯一の方法port 2は、その ACK を受信することです。

もちろん、時限待機を実装することもできますが、よりクリーンなソリューションが必要です。

もう一度質問します。 で TCP 接続を介してメッセージを送信した後、メッセージをstep 2含むパケットに対して ACK が受信されたかどうかをどのように知ることができますか?

4

3 に答える 3

4

tcp_infoこの特定のケースでは、構造が非ゼロを保持することがわかると思いますtcp_info.tcpi_unacked。経由でこれを取得しgetsockopt(TCP_INFO)ます。

注: どうやらインターフェイスが不安定です。

于 2009-01-14T16:46:35.497 に答える
2

TCP レベルの ACK はオペレーティング システムによって送信され、データがプロセスによって読み取られる前に送信できます。したがって、ACK を受信して​​も、リモート アプリケーションがメッセージに基づいて動作したこと、またはメッセージの存在が通知されたことを意味するわけではありません。

想像してみてください: TCP がメッセージの確認を確認した場合、アプリケーションはメッセージを read() して処理し (時間がかかる場合があります)、「read_ok」syscall を呼び出す必要があります。私の知る限り、これは標準のソケット API では不可能です。

未確認のデータがあるかどうかは、SIOCOUTQ ioctl (man 7 tcp) で確認できる場合があります。しかし、それはあなたの問題に対する信頼できる解決策ではありません。

これがh323の動作方法であると確信していますか? port2 が無効であるか、別の接続で使用されている場合はどうなりますか? 確認またはエラーが返されます。

于 2011-10-29T00:12:44.440 に答える