From d62c1311fb178dc80c85e5816b16f4eae4b68108 Mon Sep 17 00:00:00 2001 From: "PSp..om" Date: Fri, 5 Aug 2011 06:46:56 +0000 Subject: [PATCH] Fixed a long-standing but well hidden bug in message protocol. In the wild, I've only seen this crop up in really really odd circumstances. As it turns out, the throughput tests eventually trigger this when testing TCP. I've lost sleep over wondering when this was going to bite for real so I'm glad to have what is essentially the last known bug in message transfer fixed. This change handles the case where so far only one byte of the two byte message size has been read from the network. Rare, but it can happen. git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7976 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../jme3/network/base/MessageProtocol.java | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/engine/src/networking/com/jme3/network/base/MessageProtocol.java b/engine/src/networking/com/jme3/network/base/MessageProtocol.java index 515e6a356..b42d4746f 100644 --- a/engine/src/networking/com/jme3/network/base/MessageProtocol.java +++ b/engine/src/networking/com/jme3/network/base/MessageProtocol.java @@ -58,6 +58,7 @@ public class MessageProtocol private LinkedList messages = new LinkedList(); private ByteBuffer current; private int size; + private Byte carry; /** * Converts a message to a ByteBuffer using the Serializer @@ -108,15 +109,39 @@ public class MessageProtocol // push the data from the buffer into as // many messages as we can while( buffer.remaining() > 0 ) { - + if( current == null ) { - // We are not currently reading an object so - // grab the size. - // Note: this is somewhat limiting... int would - // be better. - size = buffer.getShort(); + + // If we have a left over carry then we need to + // do manual processing to get the short value + if( carry != null ) { + byte high = carry; + byte low = buffer.get(); + + size = (high & 0xff) << 8 | (low & 0xff); + carry = null; + } + else if( buffer.remaining() < 2 ) { + // It's possible that the supplied buffer only has one + // byte in it... and in that case we will get an underflow + // when attempting to read the short below. + + // It has to be 1 or we'd never get here... but one + // isn't enough so we stash it away. + carry = buffer.get(); + break; + } else { + // We are not currently reading an object so + // grab the size. + // Note: this is somewhat limiting... int would + // be better. + size = buffer.getShort(); + } + + // Allocate the buffer into which we'll feed the + // data as we get it current = ByteBuffer.allocate(size); - } + } if( current.remaining() <= buffer.remaining() ) { // We have at least one complete object so