Mercurial > hg > Members > nobuyasu > tightVNCProxy
annotate src/myVncProxy/MyRfbProto.java @ 82:0cbe556e2c54
remove item to reduce memory
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 03 Aug 2011 04:26:58 +0900 |
parents | 9109273b96dc |
children | d4236fd2efe1 |
rev | line source |
---|---|
24 | 1 package myVncProxy; |
54 | 2 |
25 | 3 import java.awt.Graphics; |
4 import java.awt.Image; | |
5 import java.awt.image.BufferedImage; | |
6 import java.io.BufferedOutputStream; | |
15 | 7 import java.io.BufferedReader; |
25 | 8 import java.io.ByteArrayInputStream; |
9 import java.io.ByteArrayOutputStream; | |
10 | 10 import java.io.IOException; |
43 | 11 import java.io.InputStream; |
15 | 12 import java.io.InputStreamReader; |
23 | 13 import java.net.BindException; |
10 | 14 import java.net.ServerSocket; |
15 import java.net.Socket; | |
16 import java.util.LinkedList; | |
17 | |
25 | 18 import javax.imageio.ImageIO; |
19 | |
54 | 20 import myVncProxy.MulticastQueue.Client; |
21 | |
40 | 22 import java.util.concurrent.ExecutorService; |
23 import java.util.concurrent.Executors; | |
80 | 24 import java.util.zip.DataFormatException; |
25 import java.util.zip.Deflater; | |
26 import java.util.zip.Inflater; | |
40 | 27 import java.io.OutputStream; |
10 | 28 |
29 class MyRfbProto extends RfbProto { | |
43 | 30 final static String versionMsg_3_998 = "RFB 003.998\n"; |
65 | 31 /** |
32 * CheckMillis is one of new msgType for RFB 3.998. | |
33 */ | |
77 | 34 final static int SpeedCheckMillis = 4; |
82
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
35 private static final int INFLATE_BUFSIZE = 1024*1024; |
65 | 36 boolean printStatusFlag = false; |
37 long startCheckTime; | |
54 | 38 |
18 | 39 private int messageType; |
40 private int rectangles; | |
23 | 41 private int rectX; |
42 private int rectY; | |
43 private int rectW; | |
44 private int rectH; | |
18 | 45 private int encoding; |
27 | 46 private int zLen; |
18 | 47 |
23 | 48 private ServerSocket servSock; |
49 private int acceptPort; | |
10 | 50 private byte initData[]; |
54 | 51 private LinkedList<Socket> cliListTmp; |
52 private LinkedList<Socket> cliList; | |
53 private LinkedList<Thread> sendThreads; | |
27 | 54 boolean createBimgFlag; |
54 | 55 |
40 | 56 ExecutorService executor; |
54 | 57 |
25 | 58 byte[] pngBytes; |
54 | 59 |
82
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
60 private MulticastQueue<byte[]> multicastqueue = new MostRecentMultiCast<byte[]>(10); |
80 | 61 private int clients = 0; |
81
9109273b96dc
consume too much memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
80
diff
changeset
|
62 private Inflater inflater = new Inflater(); |
54 | 63 |
64 MyRfbProto(String h, int p, VncViewer v) throws IOException { | |
10 | 65 super(h, p, v); |
54 | 66 cliList = new LinkedList<Socket>(); |
67 cliListTmp = new LinkedList<Socket>(); | |
27 | 68 createBimgFlag = false; |
61 | 69 // sendThreads = new LinkedList<Thread>(); |
54 | 70 // executor = Executors.newCachedThreadPool(); |
71 // executor = Executors.newSingleThreadExecutor(); | |
10 | 72 } |
73 | |
13 | 74 MyRfbProto(String h, int p) throws IOException { |
75 super(h, p); | |
54 | 76 cliList = new LinkedList<Socket>(); |
77 cliListTmp = new LinkedList<Socket>(); | |
27 | 78 createBimgFlag = false; |
61 | 79 // sendThreads = new LinkedList<Thread>(); |
54 | 80 // executor = Executors.newCachedThreadPool(); |
81 // executor = Executors.newSingleThreadExecutor(); | |
13 | 82 } |
24 | 83 |
44 | 84 // over write |
43 | 85 void writeVersionMsg() throws IOException { |
86 clientMajor = 3; | |
87 if (serverMinor >= 9) { | |
54 | 88 clientMinor = 9; |
89 os.write(versionMsg_3_998.getBytes()); | |
43 | 90 } else if (serverMajor > 3 || serverMinor >= 8) { |
91 clientMinor = 8; | |
92 os.write(versionMsg_3_8.getBytes()); | |
93 } else if (serverMinor >= 9) { | |
94 clientMinor = 9; | |
95 os.write(versionMsg_3_998.getBytes()); | |
96 } else if (serverMinor >= 7) { | |
97 clientMinor = 7; | |
98 os.write(versionMsg_3_7.getBytes()); | |
99 } else { | |
100 clientMinor = 3; | |
101 os.write(versionMsg_3_3.getBytes()); | |
102 } | |
103 protocolTightVNC = false; | |
104 initCapabilities(); | |
105 } | |
106 | |
54 | 107 void initServSock(int port) throws IOException { |
10 | 108 servSock = new ServerSocket(port); |
23 | 109 acceptPort = port; |
10 | 110 } |
54 | 111 |
112 // 5550を開けるが、開いてないなら+1のポートを開ける。 | |
80 | 113 void selectPort(int p) { |
114 int port = p; | |
54 | 115 while (true) { |
116 try { | |
80 | 117 initServSock(port); |
23 | 118 break; |
54 | 119 } catch (BindException e) { |
80 | 120 port++; |
23 | 121 continue; |
54 | 122 } catch (IOException e) { |
10 | 123 |
23 | 124 } |
125 } | |
80 | 126 System.out.println("accept port = " + port); |
23 | 127 } |
54 | 128 |
129 int getAcceptPort() { | |
23 | 130 return acceptPort; |
131 } | |
54 | 132 |
10 | 133 void setSoTimeout(int num) throws IOException { |
134 servSock.setSoTimeout(num); | |
135 } | |
54 | 136 |
10 | 137 Socket accept() throws IOException { |
138 return servSock.accept(); | |
139 } | |
140 | |
54 | 141 void addSock(Socket sock) { |
10 | 142 cliList.add(sock); |
143 } | |
54 | 144 |
145 void addSockTmp(Socket sock) { | |
146 System.out.println("connected " + sock.getInetAddress()); | |
27 | 147 cliListTmp.add(sock); |
148 } | |
54 | 149 |
10 | 150 boolean markSupported() { |
151 return is.markSupported(); | |
152 } | |
54 | 153 |
10 | 154 void readServerInit() throws IOException { |
54 | 155 |
78 | 156 is.mark(255); |
10 | 157 skipBytes(20); |
158 int nlen = readU32(); | |
54 | 159 int blen = 20 + 4 + nlen; |
10 | 160 initData = new byte[blen]; |
78 | 161 is.reset(); |
10 | 162 |
78 | 163 is.mark(blen); |
10 | 164 readFully(initData); |
78 | 165 is.reset(); |
54 | 166 |
10 | 167 framebufferWidth = readU16(); |
168 framebufferHeight = readU16(); | |
169 bitsPerPixel = readU8(); | |
170 depth = readU8(); | |
171 bigEndian = (readU8() != 0); | |
172 trueColour = (readU8() != 0); | |
173 redMax = readU16(); | |
174 greenMax = readU16(); | |
175 blueMax = readU16(); | |
176 redShift = readU8(); | |
177 greenShift = readU8(); | |
178 blueShift = readU8(); | |
179 byte[] pad = new byte[3]; | |
180 readFully(pad); | |
181 int nameLength = readU32(); | |
182 byte[] name = new byte[nameLength]; | |
183 readFully(name); | |
184 desktopName = new String(name); | |
185 | |
186 // Read interaction capabilities (TightVNC protocol extensions) | |
187 if (protocolTightVNC) { | |
188 int nServerMessageTypes = readU16(); | |
189 int nClientMessageTypes = readU16(); | |
190 int nEncodingTypes = readU16(); | |
191 readU16(); | |
192 readCapabilityList(serverMsgCaps, nServerMessageTypes); | |
193 readCapabilityList(clientMsgCaps, nClientMessageTypes); | |
194 readCapabilityList(encodingCaps, nEncodingTypes); | |
195 } | |
196 | |
197 inNormalProtocol = true; | |
198 } | |
199 | |
54 | 200 void sendRfbVersion(OutputStream os) throws IOException { |
201 os.write(versionMsg_3_998.getBytes()); | |
43 | 202 } |
54 | 203 |
45 | 204 void readVersionMsg(InputStream is) throws IOException { |
205 | |
206 byte[] b = new byte[12]; | |
207 | |
208 is.read(b); | |
209 | |
210 if ((b[0] != 'R') || (b[1] != 'F') || (b[2] != 'B') || (b[3] != ' ') | |
211 || (b[4] < '0') || (b[4] > '9') || (b[5] < '0') || (b[5] > '9') | |
212 || (b[6] < '0') || (b[6] > '9') || (b[7] != '.') | |
213 || (b[8] < '0') || (b[8] > '9') || (b[9] < '0') || (b[9] > '9') | |
214 || (b[10] < '0') || (b[10] > '9') || (b[11] != '\n')) { | |
215 throw new IOException("Host " + host + " port " + port | |
216 + " is not an RFB server"); | |
217 } | |
218 | |
219 serverMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0'); | |
220 serverMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0'); | |
221 | |
222 if (serverMajor < 3) { | |
223 throw new IOException( | |
224 "RFB server does not support protocol version 3"); | |
54 | 225 } |
226 | |
227 } | |
228 | |
43 | 229 void sendSecurityType(OutputStream os) throws IOException { |
230 // number-of-security-types | |
231 os.write(1); | |
54 | 232 // security-types |
43 | 233 // 1:None |
234 os.write(1); | |
235 } | |
54 | 236 |
46
11da7dacbc1a
modify MyRfbProto.java and acceptThread.java add readSecType
e085711
parents:
45
diff
changeset
|
237 void readSecType(InputStream is) throws IOException { |
11da7dacbc1a
modify MyRfbProto.java and acceptThread.java add readSecType
e085711
parents:
45
diff
changeset
|
238 byte[] b = new byte[1]; |
11da7dacbc1a
modify MyRfbProto.java and acceptThread.java add readSecType
e085711
parents:
45
diff
changeset
|
239 is.read(b); |
11da7dacbc1a
modify MyRfbProto.java and acceptThread.java add readSecType
e085711
parents:
45
diff
changeset
|
240 |
11da7dacbc1a
modify MyRfbProto.java and acceptThread.java add readSecType
e085711
parents:
45
diff
changeset
|
241 } |
54 | 242 |
47
b2bf4e44504a
modify MyRfbProto.java and acceptThread.java , add sendSecResult
e085711
parents:
46
diff
changeset
|
243 void sendSecResult(OutputStream os) throws IOException { |
b2bf4e44504a
modify MyRfbProto.java and acceptThread.java , add sendSecResult
e085711
parents:
46
diff
changeset
|
244 byte[] b = castIntByte(0); |
b2bf4e44504a
modify MyRfbProto.java and acceptThread.java , add sendSecResult
e085711
parents:
46
diff
changeset
|
245 os.write(b); |
b2bf4e44504a
modify MyRfbProto.java and acceptThread.java , add sendSecResult
e085711
parents:
46
diff
changeset
|
246 } |
54 | 247 |
43 | 248 void readClientInit(InputStream in) throws IOException { |
249 byte[] b = new byte[0]; | |
250 in.read(b); | |
251 } | |
54 | 252 |
253 void sendInitData(OutputStream os) throws IOException { | |
254 os.write(initData); | |
10 | 255 } |
256 | |
54 | 257 |
258 void sendPngImage() { | |
259 try { | |
260 for (Socket cli : cliListTmp) { | |
261 try { | |
27 | 262 sendPngData(cli); |
263 addSock(cli); | |
54 | 264 } catch (IOException e) { |
27 | 265 // if socket closed |
266 cliListTmp.remove(cli); | |
267 } | |
268 } | |
54 | 269 // System.out.println("cliSize="+cliSize()); |
270 } catch (Exception e) { | |
27 | 271 } |
272 cliListTmp.clear(); | |
273 } | |
274 | |
15 | 275 boolean ready() throws IOException { |
276 BufferedReader br = new BufferedReader(new InputStreamReader(is)); | |
277 return br.ready(); | |
54 | 278 } |
10 | 279 |
54 | 280 int cliSize() { |
10 | 281 return cliList.size(); |
54 | 282 } |
283 | |
284 void printNumBytesRead() { | |
285 System.out.println("numBytesRead=" + numBytesRead); | |
286 } | |
287 | |
288 | |
61 | 289 |
54 | 290 void regiFramebufferUpdate() throws IOException { |
78 | 291 is.mark(20); |
80 | 292 messageType = readU8(); // 0 |
293 skipBytes(1); // 1 | |
294 rectangles = readU16(); // 2 | |
295 rectX = readU16(); // 4 | |
296 rectY = readU16(); // 6 | |
297 rectW = readU16(); // 8 | |
298 rectH = readU16(); // 10 | |
299 encoding = readU32(); // 12 | |
78 | 300 System.out.println("encoding = "+encoding); |
80 | 301 if (encoding == EncodingZRLE) |
27 | 302 zLen = readU32(); |
80 | 303 else |
304 zLen = 0; | |
78 | 305 is.reset(); |
67 | 306 /* |
307 int dataLen; | |
308 switch (encoding) { | |
309 case RfbProto.EncodingRaw: | |
310 dataLen = rectW * rectH * 4 + 16; | |
311 mark(dataLen); | |
312 break; | |
313 case RfbProto.EncodingCopyRect: | |
314 dataLen = 16 + 4; | |
315 mark(dataLen); | |
316 break; | |
317 case RfbProto.EncodingRRE: | |
318 case RfbProto.EncodingCoRRE: | |
319 case RfbProto.EncodingHextile: | |
320 | |
321 case RfbProto.EncodingZlib: | |
322 case RfbProto.EncodingTight: | |
323 case RfbProto.EncodingZRLE: | |
324 dataLen = zLen + 20; | |
325 mark(dataLen); | |
326 break; | |
327 default: | |
328 dataLen = 1000000; | |
329 mark(dataLen); | |
330 } | |
331 | |
332 */ | |
333 | |
15 | 334 } |
54 | 335 |
61 | 336 int checkAndMark() throws IOException { |
337 int dataLen; | |
54 | 338 switch (encoding) { |
23 | 339 case RfbProto.EncodingRaw: |
39 | 340 dataLen = rectW * rectH * 4 + 16; |
78 | 341 is.mark(dataLen); |
23 | 342 break; |
67 | 343 case RfbProto.EncodingCopyRect: |
344 dataLen = 16 + 4; | |
78 | 345 is.mark(dataLen); |
67 | 346 break; |
347 case RfbProto.EncodingRRE: | |
348 case RfbProto.EncodingCoRRE: | |
349 case RfbProto.EncodingHextile: | |
80 | 350 case RfbProto.EncodingTight: |
351 dataLen = zLen + 20; | |
352 is.mark(dataLen); | |
353 break; | |
67 | 354 case RfbProto.EncodingZlib: |
27 | 355 case RfbProto.EncodingZRLE: |
54 | 356 dataLen = zLen + 20; |
78 | 357 is.mark(dataLen); |
358 break; | |
359 case RfbProto.EncodingXCursor: | |
360 case RfbProto.EncodingRichCursor: | |
361 int pixArray = rectW * rectH * 4; | |
362 int u8Array = (int)Math.floor((rectW + 7)/8) * rectH; | |
363 dataLen = pixArray + u8Array; | |
364 printFramebufferUpdate(); | |
365 is.mark(dataLen); | |
27 | 366 break; |
23 | 367 default: |
61 | 368 dataLen = 1000000; |
78 | 369 is.mark(dataLen); |
54 | 370 } |
61 | 371 return dataLen; |
372 } | |
65 | 373 |
81
9109273b96dc
consume too much memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
80
diff
changeset
|
374 void readSendData(int dataLen) throws IOException, DataFormatException { |
9109273b96dc
consume too much memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
80
diff
changeset
|
375 byte b[] = new byte[dataLen]; |
9109273b96dc
consume too much memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
80
diff
changeset
|
376 readFully(b); |
9109273b96dc
consume too much memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
80
diff
changeset
|
377 |
9109273b96dc
consume too much memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
80
diff
changeset
|
378 if (b[0]==RfbProto.FramebufferUpdate) { |
9109273b96dc
consume too much memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
80
diff
changeset
|
379 int encoding = ((b[12]*256+b[13])*256+b[14])*256+b[15]; |
9109273b96dc
consume too much memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
80
diff
changeset
|
380 if (encoding==RfbProto.EncodingZlib||encoding==RfbProto.EncodingZRLE) { |
82
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
381 int len; |
81
9109273b96dc
consume too much memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
80
diff
changeset
|
382 inflater.setInput(b, 20, b.length-20); |
82
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
383 do { |
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
384 byte inf[] = new byte[INFLATE_BUFSIZE+20]; |
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
385 len = inflater.inflate(inf,20,inf.length-20); |
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
386 for(int i = 0;i<20;i++) inf[i] = b[i]; |
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
387 inf[16+0] = (byte) ((len >>> 24) & 0xFF); |
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
388 inf[16+1] = (byte) ((len >>> 16) & 0xFF); |
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
389 inf[16+2] = (byte) ((len >>> 8) & 0xFF); |
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
390 inf[16+3] = (byte) ((len >>> 0) & 0xFF); |
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
391 multicastqueue.put(inf); |
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
392 } while (len ==INFLATE_BUFSIZE); |
81
9109273b96dc
consume too much memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
80
diff
changeset
|
393 is.reset(); |
9109273b96dc
consume too much memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
80
diff
changeset
|
394 return; |
9109273b96dc
consume too much memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
80
diff
changeset
|
395 } |
9109273b96dc
consume too much memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
80
diff
changeset
|
396 } |
9109273b96dc
consume too much memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
80
diff
changeset
|
397 multicastqueue.put(b); |
78 | 398 is.reset(); |
65 | 399 |
80 | 400 // It may be compressed. We can inflate here to avoid repeating clients decompressing here, |
401 // but it may generate too many large data. It is better to do it in each client. | |
81
9109273b96dc
consume too much memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
80
diff
changeset
|
402 // But we have do inflation for all input data, so we have to do it here. |
61 | 403 /* |
404 for (Socket cli : cliList) { | |
405 try { | |
406 OutputStream out = cli.getOutputStream(); | |
407 executor.execute(new SendThread(out, buffer)); | |
408 } catch (IOException e) { | |
409 // if client socket closed | |
410 cliListTmp.remove(cli); | |
411 } catch (Exception e) { | |
412 | |
413 } | |
414 | |
415 } | |
416 */ | |
417 } | |
81
9109273b96dc
consume too much memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
80
diff
changeset
|
418 void sendDataToClient() throws Exception { |
61 | 419 regiFramebufferUpdate(); |
420 int dataLen = checkAndMark(); | |
421 readSendData(dataLen); | |
23 | 422 } |
54 | 423 |
424 BufferedImage createBufferedImage(Image img) { | |
425 BufferedImage bimg = new BufferedImage(img.getWidth(null), | |
426 img.getHeight(null), BufferedImage.TYPE_INT_RGB); | |
27 | 427 |
25 | 428 Graphics g = bimg.getGraphics(); |
429 g.drawImage(img, 0, 0, null); | |
430 g.dispose(); | |
431 return bimg; | |
432 } | |
433 | |
54 | 434 void createPngBytes(BufferedImage bimg) throws IOException { |
435 pngBytes = getImageBytes(bimg, "png"); | |
25 | 436 } |
54 | 437 |
438 byte[] getBytes(BufferedImage img) throws IOException { | |
25 | 439 byte[] b = getImageBytes(img, "png"); |
440 return b; | |
441 } | |
54 | 442 |
443 byte[] getImageBytes(BufferedImage image, String imageFormat) | |
444 throws IOException { | |
25 | 445 ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
446 BufferedOutputStream os = new BufferedOutputStream(bos); | |
447 image.flush(); | |
448 ImageIO.write(image, imageFormat, os); | |
449 os.flush(); | |
450 os.close(); | |
451 return bos.toByteArray(); | |
452 } | |
453 | |
54 | 454 void sendPngData(Socket sock) throws IOException { |
26 | 455 byte[] dataLength = castIntByte(pngBytes.length); |
456 sock.getOutputStream().write(dataLength); | |
25 | 457 sock.getOutputStream().write(pngBytes); |
458 } | |
54 | 459 |
460 byte[] castIntByte(int len) { | |
26 | 461 byte[] b = new byte[4]; |
54 | 462 b[0] = (byte) ((len >>> 24) & 0xFF); |
463 b[1] = (byte) ((len >>> 16) & 0xFF); | |
464 b[2] = (byte) ((len >>> 8) & 0xFF); | |
465 b[3] = (byte) ((len >>> 0) & 0xFF); | |
26 | 466 return b; |
467 } | |
54 | 468 |
469 BufferedImage createBimg() throws IOException { | |
25 | 470 BufferedImage bimg = ImageIO.read(new ByteArrayInputStream(pngBytes)); |
471 return bimg; | |
472 } | |
65 | 473 /* |
54 | 474 void readPngData() throws IOException { |
25 | 475 pngBytes = new byte[is.available()]; |
476 readFully(pngBytes); | |
477 } | |
65 | 478 */ |
54 | 479 void printFramebufferUpdate() { |
480 | |
18 | 481 System.out.println("messageType=" + messageType); |
54 | 482 System.out.println("rectangles=" + rectangles); |
18 | 483 System.out.println("encoding=" + encoding); |
78 | 484 System.out.println("rectX = "+rectX+": rectY = "+rectY); |
485 System.out.println("rectW = "+rectW+": rectH = "+rectH); | |
54 | 486 switch (encoding) { |
23 | 487 case RfbProto.EncodingRaw: |
54 | 488 System.out.println("rectW * rectH * 4 + 16 =" + rectW * rectH * 4 |
489 + 16); | |
23 | 490 break; |
491 default: | |
492 } | |
18 | 493 } |
65 | 494 |
77 | 495 void readSpeedCheck() throws IOException { |
496 byte[] b = new byte[1]; | |
65 | 497 readFully(b); |
498 } | |
499 | |
77 | 500 void startSpeedCheck() { |
66 | 501 byte[] b = new byte[2]; |
77 | 502 b[0] = (byte) SpeedCheckMillis; |
66 | 503 b[1] = (byte) 0; |
504 startCheckTime = System.currentTimeMillis(); | |
505 System.out.println("startChckTime = "+ startCheckTime); | |
65 | 506 multicastqueue.put(b); |
507 } | |
508 | |
77 | 509 void endSpeedCheck() { |
65 | 510 long accTime = System.currentTimeMillis(); |
511 long time = accTime - startCheckTime; | |
512 System.out.println("checkMillis: " + time); | |
513 } | |
514 | |
515 void printStatus() { | |
516 System.out.println(); | |
517 } | |
518 | |
519 synchronized void changeStatusFlag() { | |
520 printStatusFlag = true; | |
521 } | |
522 | |
523 void printMills() { | |
524 if(printStatusFlag) { | |
525 | |
526 changeStatusFlag(); | |
527 } else { | |
528 changeStatusFlag(); | |
529 } | |
530 } | |
531 | |
43 | 532 |
71 | 533 void newClient(AcceptThread acceptThread, final Socket newCli, |
54 | 534 final OutputStream os, final InputStream is) throws IOException { |
535 // createBimgFlag = true; | |
536 // rfb.addSockTmp(newCli); | |
537 // addSock(newCli); | |
538 final Client<byte[]> c = multicastqueue.newClient(); | |
539 Runnable sender = new Runnable() { | |
540 public void run() { | |
80 | 541 |
542 Deflater deflater = new Deflater(); | |
54 | 543 try { |
65 | 544 /** |
545 * initial connection of RFB protocol | |
546 */ | |
54 | 547 sendRfbVersion(os); |
548 readVersionMsg(is); | |
549 sendSecurityType(os); | |
550 readSecType(is); | |
551 sendSecResult(os); | |
552 readClientInit(is); | |
553 sendInitData(os); | |
43 | 554 |
54 | 555 for (;;) { |
556 byte[] b = c.poll(); | |
80 | 557 if (b[0]==RfbProto.FramebufferUpdate) { |
558 int encoding = ((b[12]*256+b[13])*256+b[14])*256+b[15]; | |
559 if (encoding==RfbProto.EncodingZlib||encoding==RfbProto.EncodingZRLE) { | |
82
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
560 byte[] c1 = new byte[INFLATE_BUFSIZE]; |
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
561 int len=0,len1,clen; |
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
562 do { |
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
563 clen = ((b[16]*256+b[17])*256+b[18])*256+b[19]; |
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
564 deflater.setInput(b,20,clen); |
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
565 len1 = deflater.deflate(c1); |
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
566 if (clen==INFLATE_BUFSIZE) b = c.poll(); |
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
567 len += len1; |
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
568 } while(clen== INFLATE_BUFSIZE); |
80 | 569 byte[] blen = castIntByte(len); |
81
9109273b96dc
consume too much memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
80
diff
changeset
|
570 os.write(b,0,16); |
80 | 571 os.write(blen,0,4); |
82
0cbe556e2c54
remove item to reduce memory
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
81
diff
changeset
|
572 os.write(c1,0,len); |
80 | 573 } |
574 } else | |
575 os.write(b, 0, b.length); | |
54 | 576 } |
577 } catch (IOException e) { | |
65 | 578 /** |
579 * if socket closed | |
580 */ | |
54 | 581 // cliList.remove(newCli); |
582 } | |
583 | |
584 } | |
585 | |
586 }; | |
80 | 587 clients++; |
54 | 588 new Thread(sender).start(); |
589 | |
590 } | |
66 | 591 |
77 | 592 void speedCheckMillis() { |
66 | 593 |
594 Runnable stdin = new Runnable() { | |
595 public void run() { | |
596 int c; | |
597 try { | |
598 while( (c = System.in.read()) != -1 ) { | |
599 switch(c) { | |
600 case 's': | |
601 break; | |
602 default: | |
77 | 603 startSpeedCheck(); |
66 | 604 break; |
605 } | |
606 } | |
607 }catch(IOException e){ | |
608 System.out.println(e); | |
609 } | |
610 } | |
611 }; | |
612 | |
613 new Thread(stdin).start(); | |
614 } | |
615 | |
54 | 616 } |
66 | 617 |
618 |