2

Nettyを使用しているプログラムで非常に奇妙な問題が発生しています。

ポートをリッスンし、メッセージを解析しています(FrameDecoder実装を使用)。1つの接続を受信して​​いる場合はすべて正常に機能していますが、同じポートで2つの接続を受信して​​いる場合(それぞれが異なるサーバーから)、corruptedFrameExceptionが発生するというまれですが重大な状況が発生します。

この問題は、プログラムがまったく同じタイムスタンプのTCPパケットを受信した場合(非常に高速で情報を送信した場合)に発生します。

  1. サーバー1からのTCPパケット
  2. サーバー2からのTCPパケット
  3. サーバー1からのTCPパケット(これは、箇条書き1で開始されたメッセージの続きです)
  4. サーバー2からのTCPパケット(これは、箇条書き2で開始されたメッセージの続きです)

私のプログラムは、実際のメッセージが1&3と2&4であることを知る代わりに、1と2をメッセージとして解析しようとします。どこかで読んだのですが、チャネル接続ごとに新しいFrameDecoderをインスタンス化する必要があるかもしれませんが、わかりません。どのように正確にそれを行うか。起動時にデコーダーをパイプラインに追加していますが、特定のチャネルに新しいデコーダーを追加する方法がわかりません

私が経験している例外は次のとおりです。

org.jboss.netty.handler.codec.frame.CorruptedFrameException: Adjusted frame length (0) is less than lengthFieldEndOffset: 2
    at org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:340) ~[netty-3.1.5.GA.jar:]
    at org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:282) ~[netty-3.1.5.GA.jar:]
    at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:214) ~[netty-3.1.5.GA.jar:]
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:345) ~[netty-3.1.5.GA.jar:]
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:332) ~[netty-3.1.5.GA.jar:]
    at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:323) ~[netty-3.1.5.GA.jar:]
    at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:275) ~[netty-3.1.5.GA.jar:]
    at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:196) ~[netty-3.1.5.GA.jar:]
    at org.jboss.netty.util.internal.IoWorkerRunnable.run(IoWorkerRunnable.java:46) ~[netty-3.1.5.GA.jar:]
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:651) [na:1.5.0]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:676) [na:1.5.0]
    at java.lang.Thread.run(Thread.java:595) [na:1.5.0]

org.jboss.netty.handler.codec.frame.TooLongFrameException: Adjusted frame length exceeds 4096: 8224
        at org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:296) ~[netty-3.1.5.GA.jar:]
        at org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:282) ~[netty-3.1.5.GA.jar:]
        at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:216) ~[netty-3.1.5.GA.jar:]
        at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:345) ~[netty-3.1.5.GA.jar:]
        at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:332) ~[netty-3.1.5.GA.jar:]
        at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:323) ~[netty-3.1.5.GA.jar:]
        at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:275) ~[netty-3.1.5.GA.jar:]
        at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:196) ~[netty-3.1.5.GA.jar:]
        at org.jboss.netty.util.internal.IoWorkerRunnable.run(IoWorkerRunnable.java:46) ~[netty-3.1.5.GA.jar:]
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:651) [na:1.5.0]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:676) [na:1.5.0]
        at java.lang.Thread.run(Thread.java:595) [na:1.5.0]
4

2 に答える 2

1

フレームデコーダの新しいオブジェクトを新しい(2番目の?)チャネルに追加する必要があります。重複する例外は、同じチャネルを使用しているためです。

  1. サーバーのブートストラップは、適切なエンコーダーとデコーダーを使用してすべての新しいチャネルを構成するパイプラインファクトリを使用します。
  2. リモートクライアントがサーバーに接続するたびに、サーバーは独自のチャネルオブジェクトを作成します。
  3. 使用しているChannelPipelineFactoryの実装。pipe ()メソッドが呼び出されるたびに、フレームデコーダーの新しいインスタンスが作成されることを確認してください。
  4. @Sharableアノテーションは、文書化のみを目的としています。コード/ロジックではないので、使っても何の影響もありません。ただのマーカーです。
于 2012-06-05T05:58:55.937 に答える
0

チャンネル間でFrameDecoderを「共有しない」必要があります。FrameDecoderには@Sharableの注釈が付いていないため、共有することはできません。それがここでの問題の原因です。

于 2012-06-04T13:33:14.980 に答える