@@ -209,15 +209,16 @@ public void dispose() {
209209
210210
211211 public void run () {
212+ byte [] readBuffer = new byte [2048 ]; // Ethernet MTU = 1500 B
212213 while (Thread .currentThread () == thread ) {
213214 try {
214215 while (input != null ) {
215- int value ;
216+ int readCount ;
216217
217218 // try to read a byte using a blocking read.
218219 // An exception will occur when the sketch is exits.
219220 try {
220- value = input .read ();
221+ readCount = input .read (readBuffer , 0 , readBuffer . length );
221222 } catch (SocketException e ) {
222223 System .err .println ("Client SocketException: " + e .getMessage ());
223224 // the socket had a problem reading so don't try to read from it again.
@@ -226,7 +227,7 @@ public void run() {
226227 }
227228
228229 // read returns -1 if end-of-stream occurs (for example if the host disappears)
229- if (value == -1 ) {
230+ if (readCount == -1 ) {
230231 System .err .println ("Client got end-of-stream." );
231232 stop ();
232233 return ;
@@ -235,31 +236,36 @@ public void run() {
235236 synchronized (bufferLock ) {
236237 // todo: at some point buffer should stop increasing in size,
237238 // otherwise it could use up all the memory.
238- if (bufferLast == buffer .length ) {
239- if (bufferIndex > 0 ) {
240- // compact the buffer
241- int bufferLength = bufferLast - bufferIndex ;
242- System .arraycopy (buffer , bufferIndex , buffer , 0 , bufferLength );
243- bufferLast -= bufferIndex ;
244- bufferIndex = 0 ;
245- } else {
246- // resize the buffer
247- byte temp [] = new byte [bufferLast << 1 ];
248- System .arraycopy (buffer , 0 , temp , 0 , bufferLast );
249- buffer = temp ;
239+ int freeBack = buffer .length - bufferLast ;
240+ if (readCount > freeBack ) {
241+ // not enough space at the back
242+ int bufferLength = bufferLast - bufferIndex ;
243+ byte [] targetBuffer = buffer ;
244+ if (bufferLength + readCount > buffer .length ) {
245+ // can't fit even after compacting, resize the buffer
246+ // find the next power of two which can fit everything in
247+ int newSize = Integer .highestOneBit (bufferLength + readCount - 1 ) << 1 ;
248+ targetBuffer = new byte [newSize ];
250249 }
250+ // compact the buffer (either in-place or into the new bigger buffer)
251+ System .arraycopy (buffer , bufferIndex , targetBuffer , 0 , bufferLength );
252+ bufferLast -= bufferIndex ;
253+ bufferIndex = 0 ;
254+ buffer = targetBuffer ;
251255 }
252- buffer [bufferLast ++] = (byte )value ;
256+ // copy all newly read bytes into the buffer
257+ System .arraycopy (readBuffer , 0 , buffer , bufferLast , readCount );
258+ bufferLast += readCount ;
253259 }
254260
255261 // now post an event
256262 if (clientEventMethod != null ) {
257263 try {
258264 clientEventMethod .invoke (parent , new Object [] { this });
259- } catch (Exception e ) {
260- System .err .println ("error, disabling clientEvent() for " + host );
261- e .printStackTrace ();
262- clientEventMethod = null ;
265+ } catch (Exception e ) {
266+ System .err .println ("error, disabling clientEvent() for " + host );
267+ e .printStackTrace ();
268+ clientEventMethod = null ;
263269 }
264270 }
265271 }
0 commit comments