повреждение буфера в netty - PullRequest
0 голосов
/ 09 марта 2012

Я получил странную ошибку при использовании netty (с верблюдом), мы используем для связи LengthFieldBasedFrameDecoder, клиент является программой-сокетом от третьей стороны, мы используем netty (компонент camel-netty) на стороне сервера.

иногда два сообщения «объединяются» в одно, и, следовательно, предстоящие данные ошибочны.

например:

клиент отправляет два сообщения:

[10] AAAAAAAAAAAAAAAAи [10] BBBBBBBBBBBBBBBB

, где [10] - длина байтов, а AAAAAAAAAA - данные.

, но на сервере мы получили [10] AAAAAA [10] BBBBBBBBBBBBBBBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA* Кажется, первое сообщение было разделено на второе, поэтому декодер интерпретировал данные как:

[10] AAAAAA [10] BBBBBBBB

и

BBBBBBBAAAAAAAAAAA...................................................

, чтобы первое сообщение было правильной по длине, но неверным в данных, а второе сообщение неправильной по длине "BB" и получило намного более длинный пакет данных.

надеюсь, я четко описал, кто-нибудь встречал это раньше?

Ответы [ 3 ]

2 голосов
/ 09 марта 2012

Звучит так, как будто вы пишете в один поток в двух потоках.

1 голос
/ 04 июля 2012

Ваш LengthFieldBasedFrameDecoder расширяется FrameDecoder? И это синглтон или нет?

На самом деле я усмотрел ту же проблему, и я согласен с точкой зрения Питера;

Я взглянул на FrameDecoder и обнаружил, что есть свойство ChannelBuffer с именем "cumulation" , которое будет доступно всем каналам декодера.

и давайте посмотрим на метод FrameDecoder.messageReceived:

@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {

    Object m = e.getMessage();
    if (!(m instanceof ChannelBuffer)) {
        ctx.sendUpstream(e);
        return;
    }

    ChannelBuffer input = (ChannelBuffer) m; // here is the buffer from the channel
    if (!input.readable()) {
        return;
    }

    ChannelBuffer cumulation = cumulation(ctx); // here is the buffer wrapped by the FrameDecoder
    if (cumulation.readable()) {
        cumulation.discardReadBytes();

        // where "[10]AAA[10]BBBBB" happens
        cumulation.writeBytes(input); 

        // if code run here,we will get the wrong buffer
        callDecode(ctx, e.getChannel(), cumulation, e.getRemoteAddress());
    } else {
        callDecode(ctx, e.getChannel(), input, e.getRemoteAddress());
        if (input.readable()) {
            cumulation.writeBytes(input);
        }
    }
}

Я думаю, что правильный способ использования FrameDecoder - сделать его многозадачным.

1 голос
/ 18 марта 2012

хорошо, это оказалось "ошибкой" компонента camel-netty, позже я опубликую исправление для проекта camel.Перед этим, пожалуйста, будьте осторожны, используя компонент camel-netty, особенно не используйте кодеры / декодеры, не помеченные аннотацией @sharable, это приведет к проблеме, так как состояние может быть общим для разных соединений.

...