2016-04-13 1 views
0

J'ai un problème avec un décodeur personnalisé que j'ai développé et je ne suis pas sûr de ce que je fais mal.Sparodic OutOfBounds problème avec Netty 4.01 CR6

Le format de message que nous recevons contient un HEADER, un BODY et un TRAILER. L'en-tête est de 1 octet et est un STX (0x02) Le corps est de longueur variable La bande-annonce est de 2 octets qui contiennent un ETX (0x03) suivi d'un LRC.

donc un message typique pourrait ressembler à:

STX BODY ETX LRC 
02 37000000 06 18 

La sortie du décodeur doit être le message sans l'octet de commande STX. Ainsi, le message envoyé est sur:

BODY  ETX LRC 
37000000 06 18 

Nous avons étendu la DelimiterBasedFrameDecoder et a défini le ETX comme séparateur. L'intention du décodeur est de lire l'octet suivant, de l'ajouter au tampon, puis de l'envoyer, de cette façon nous envoyons un message complet. Notre méthode de décodage ressemble à ceci:

protected Object decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception { 
    Object frame = super.decode(ctx, buffer); 

    if (frame == null) { 
     return null; 
    } 
    ByteBuf msg = null; 

    if (frame instanceof ByteBuf) { 
     msg = Unpooled.copiedBuffer((ByteBuf) frame); 
     msg.writeByte(buffer.readByte()); 
     ((ByteBuf) frame).release(); 
    } 

    while (msg.getByte(0) != STX) { 
     msg.readByte(); 
     msg = msg.discardReadBytes(); 
    } 

    return msg; 
} 

Tout fonctionne comme prévu, sauf que périodiquement nous recevons l'exception suivante.

java.lang.IndexOutOfBoundsException: readerIndex(225) + length(1) exceeds writerIndex(225): UnpooledUnsafeDirectByteBuf(ridx: 225, widx: 225, cap: 256) 

Nous utilisons Netty 4.01 CR6 et c'est un problème sporadique. Ce dont je ne suis pas sûr, c'est que c'est quelque chose que je ne fais pas correctement, ou est-ce que c'est un problème chez Netty. Comme je suis assez nouveau pour Netty, je pense que c'est quelque chose que je fais, mais je ne suis pas sûr. J'espère que quelqu'un peut m'aider à résoudre ce problème. Je suis plus qu'heureux d'afficher plus d'informations pour obtenir ce résolu, il suffit de demander.

Appréciez toute l'aide que je peux obtenir sur celui-ci.

  • Tim

Répondre

0

Cette exception signifie que vous essayez de lire un octet du bytebuf qu'il ne contient pas, parce que vous avez atteint la fin de celui-ci.

Soit le client a envoyé des données non valides, soit tous les paquets de votre protocole n'ont pas le STX dans le message. Une autre erreur couramment commise lors du décodage d'un protocole existant est que la séquence d'octets que vous utilisez comme délimiteur est utilisée dans les paquets eux-mêmes et que vous devez lire les octets octets par octets. Si vous voulez voir les paquets circuler vers votre décodeur, vous pouvez ajouter un LoggingHandler(LogLevel.INFO) au pipeline, juste avant que votre décodeur soit exécuté, il affichera donc les octets bruts en hexadécimal, afin que vous puissiez vérifier s'il contient en fait les séquences d'octets nécessaires.

Sidenote: Vous ne publiez jamais le bytebuf stocké dans msg. Cela créera des fuites de mémoire et mènera éventuellement à un MOO, assurez-vous d'appeler la libération dans un bloc try-finally, donc c'est toujours appelé