changeset 611:9a2bef3f3020

blocking fix broadcast mode
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Fri, 21 Feb 2020 11:52:14 +0900
parents 705fd8d79378
children 42ddba3af8b2
files src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java
diffstat 2 files changed, 32 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java	Thu Feb 20 17:48:24 2020 +0900
+++ b/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEDecoder.java	Fri Feb 21 11:52:14 2020 +0900
@@ -38,13 +38,15 @@
 
 public class ZRLEDecoder extends ZlibDecoder {
 	private static final int MAX_TILE_SIZE = 64;
+	private static final int RECT_HEADER_SIZE = 16;
 	private int[] decodedBitmap;
 	private int[] palette;
+	private boolean WifiMulticast;
 
 	class TileLoop {
 		private final boolean blocking;
-		final int MARGIN = 18000;
-		final int deflate_size = 60000-MARGIN;
+		final int MARGIN = 25000;
+		final int deflate_size = 62000-MARGIN;
 		private ByteBuffer c1;
 		private int width; // phase2 length
 		private FramebufferUpdateRectangle c0rect,c1rect,rect;
@@ -79,7 +81,7 @@
 		public TileLoop(TreeRFBProto rfb, int offset) {
 			prevoffset = prevLineOffset = flushOffset = offset;
 			prevC1Offset = 0;
-			if (rfb == null || offset < deflate_size + spanGap) {
+			if (rfb == null || offset < deflate_size + MARGIN) {
 				// packet size fit in broadcast send it all at once
 				blocking = false;
 			} else
@@ -120,7 +122,6 @@
 			c0rect = null;
 		}
 
-		int spanGap = 128;
 		/**
 		 * Series of tiles compose at most three rectangles. SYNC_FLUSH is necessary on
 		 * rectangle boundaries.
@@ -210,7 +211,7 @@
 						flushMuticast(rfb,bytes);
 						return;
 					}
-					c1.position(c1.position()+16); // header space
+					c1.position(c1.position()+ RECT_HEADER_SIZE); // header space
 					prevC1Offset = c1.position();
 					c1rect = new FramebufferUpdateRectangle(rect.x,c1rect.y+tileH,0,0);
 				}
@@ -224,11 +225,12 @@
 					} else { // first phase 1 case
 						c0rect = c1rect;
 					}
+					c1rect = new FramebufferUpdateRectangle(rect.x, c0rect.y+c0rect.height, 0, 0);
 					if (end) {
+						c0rect = null; // next will be first phase 1 case
 						flushMuticast(rfb,bytes);
 						return;
 					}
-					c1rect = new FramebufferUpdateRectangle(rect.x, c0rect.y+c0rect.height, 0, 0);
 					prevLineOffset = offset;
 				}
 			}
@@ -236,22 +238,32 @@
 
 		public void makeHeaderSpace() {
 			// previous rectangle is finished, make next header space and copy already compressed part
-			System.arraycopy(c1.array(),prevC1LineOffset,c1.array(),prevC1LineOffset+16,c1.position()-prevC1LineOffset);
-			c1.position(c1.position()+16);
-			prevC1Offset = prevC1LineOffset+16;
+			System.arraycopy(c1.array(),prevC1LineOffset,c1.array(),prevC1LineOffset+ RECT_HEADER_SIZE,c1.position()-prevC1LineOffset);
+			c1.position(c1.position()+ RECT_HEADER_SIZE);
+			prevC1Offset = prevC1LineOffset+ RECT_HEADER_SIZE;
 		}
 
+		/**
+		 *
+		 * @param extend   use MARGIN
+		 * @param what     reason of flush (debug purpose)
+		 * @return         packet full
+		 * @throws TransportException
+		 */
 		private boolean flushDeflator(boolean extend,String what) throws TransportException {
 			// System.out.println("flusing "+what+c1);
-			if (extend) c1.limit(c1.capacity()-16);
+			if (extend) c1.limit(c1.capacity()- RECT_HEADER_SIZE);
 			deflater.deflate(c1, Deflater.FULL_FLUSH);
 			if (c1.remaining()==0) {
 				if (!extend) {
-					c1.limit(c1.capacity()-16);
+					c1.limit(c1.capacity()- RECT_HEADER_SIZE);
 					deflater.deflate(c1, Deflater.FULL_FLUSH);
 				}
-				if (c1.remaining() == 0)
-					throw new TransportException("Multicast packet overrun", null);
+				if (c1.remaining() == 0) {
+					ByteBuffer tmp = ByteBuffer.allocate(65536);
+					deflater.deflate(tmp,Deflater.FULL_FLUSH);
+					throw new TransportException("Multicast packet overrun "+(c1.limit()+tmp.position())+" bytes required", null);
+				}
 				return true;
 			}
 			return false;
@@ -282,11 +294,11 @@
 			bufs.add(c1);
 			// rfb.getContext().checkFrameBufferRectanble(c1, bytes, flushOffset, prevoffset);
 			flushOffset = prevoffset;
-			if (rfb.isTreeManager() && rfb.connectionPresenter.isUseMulticast()) {
+			if (WifiMulticast) {
 				for (ByteBuffer buf : bufs)
 					rfb.getViewer().getRfbBroadcastListener().multicastUpdateRectangle(buf);
-			} else {
-				rfb.multicastqueue.put(bufs);
+			} else if (rfb.multicastBlocking) {
+				rfb.multicastqueue.put(bufs);  // debug purpose
 			}
 		}
 	}
@@ -304,7 +316,7 @@
 
 	public void multicastDecode(Reader reader, Renderer renderer,
 								FramebufferUpdateRectangle rect, TreeRFBProto rfb) throws TransportException {
-		ByteBuffer header = ByteBuffer.allocate(16);
+		ByteBuffer header = ByteBuffer.allocate(16); // FBU header
 		reader.read(header.array());
 		int zippedLength = (int) reader.readUInt32();
 		if (0 == zippedLength) return;
@@ -320,7 +332,7 @@
 		int maxX = rect.x + rect.width;
 		int maxY = rect.y + rect.height;
 		byte[] bytes = buf.array();
-		boolean WifiMulticast = rfbProto !=null && (rfbProto.multicastBlocking || rfbProto.getViewer().getUseMulticast());
+		WifiMulticast = rfbProto !=null && (rfbProto.multicastBlocking ||(rfbProto.isTreeManager()&&rfbProto.getViewer().getUseMulticast()));
 
 		TileLoop tileloop = new TileLoop(rfbProto, zippedLength);
 		//System.out.println("decode1: "+rect.toString());
--- a/src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java	Thu Feb 20 17:48:24 2020 +0900
+++ b/src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java	Fri Feb 21 11:52:14 2020 +0900
@@ -277,7 +277,7 @@
                         repaintController.repaintBitmap(rect);
                     } catch (Exception e) {
                         e.printStackTrace();
-                        break;
+                        continue; // we have to read all rectangles
                     }
                 } else if (rect.getEncodingType() == EncodingType.RICH_CURSOR) {
                     RichCursorDecoder.getInstance().decode(reader, renderer, rect);
@@ -432,7 +432,7 @@
         }
     }
 
-    static public boolean multiasting = false;
+    static public boolean multiasting = true;
 
     public void handleMulticastFrameBufferUpdate(ByteBuffer c1) {
         FramebufferUpdateRectangle rect = new FramebufferUpdateRectangle();