2

私は、使用可能なネットワークで動作できるはずのクライアントサーバーシステムを作成しています。接続が一度に切断される可能性があると想定し、システムは再接続して作業を続行する必要があります。Netty を使用していますが、問題が発生しています。送信したメッセージが別のホストによって受信されたことをどのように知ることができますか?

私は、この目的のために ChannelFuture を使用できると考えていました。接続された将来のリスナーで失敗した場合は、単にメッセージを再送信しようとすることができます:

ChannelFuture fut = channel.write(message);
fut.addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture future) throws Exception {
            if (!future.isSuccess()) {
                LOGGER.error("Message send failed. Message: " + message, future.getCause());
                //Queue message to be send after reconnect
            } 
        }
});

しかし、私が行ったとき、そのリスナーは決してエラーを出力しないことに気付きました。(システムがほとんど機能しないときにネットワークからプラグを抜いてこれをテストしました)また、送信したメッセージのすべての先物が「完了」状態になり、メッセージが受信されたことを確認する方法がないことに気付きました(確認メッセージを使用しません)

私が知っているように、TCP プロトコルはメッセージが受信されることを保証し、それを使用すると、どの送信パッケージが宛先に到達し、どの送信パッケージが到達しなかったかを知ることができます。Netty がそれを知ることを許さないなんて信じられません。

メッセージが配信されたことを知る良い方法はありますか?

4

2 に答える 2

6

あなたはTCPを誤解しています。TCP は、メッセージが受信されることを保証しません。これは、信頼できる順序付けられたバイト ストリームを提供します。それはあなたのメッセージについて何も知らず、リモートホストがいつ受信したかを伝えることもできません. したがって、Netty もできません。Netty は、メッセージが送信される前にオペレーティング システムのバッファーに書き込まれたことのみを通知します。これは、コードが検出するものです。

あなたのメッセージが確実に受信されたことを確認するには、受信者は明示的な確認を送り返す必要があります。これを実現する最善の方法は、プロトコルの予想される動作によって異なりますが、通常は、送信されたがまだ確認応答されていないすべてのメッセージのテーブルを維持する必要があります。

于 2013-04-29T16:06:54.483 に答える
1

あなたの未来がすることは、メッセージをネットワークに書き込むことだけです。

受信を保証するには、確認応答を実装するか、メッセージ番号を使用して要求を再送信する必要があります。

于 2015-02-07T03:19:55.547 に答える