Mercurial > hg > Members > nobuyasu > tightVNCClient
comparison src/myVncClient/MyRfbProto.java @ 62:539d09923e4b
scp firefly
author | e085711 |
---|---|
date | Sat, 09 Jul 2011 13:09:55 +0900 |
parents | 76f5994f2af2 |
children |
comparison
equal
deleted
inserted
replaced
42:129e999a2aa3 | 62:539d09923e4b |
---|---|
1 package myVncClient; | 1 package myVncClient; |
2 | |
2 import java.awt.Graphics; | 3 import java.awt.Graphics; |
3 import java.awt.Image; | 4 import java.awt.Image; |
4 import java.awt.image.BufferedImage; | 5 import java.awt.image.BufferedImage; |
5 import java.io.BufferedOutputStream; | 6 import java.io.BufferedOutputStream; |
6 import java.io.BufferedReader; | 7 import java.io.BufferedReader; |
14 import java.net.Socket; | 15 import java.net.Socket; |
15 import java.util.LinkedList; | 16 import java.util.LinkedList; |
16 | 17 |
17 import javax.imageio.ImageIO; | 18 import javax.imageio.ImageIO; |
18 | 19 |
20 import myVncClient.MulticastQueue.Client; | |
21 | |
19 import java.util.concurrent.ExecutorService; | 22 import java.util.concurrent.ExecutorService; |
20 import java.util.concurrent.Executors; | 23 import java.util.concurrent.Executors; |
21 import java.io.OutputStream; | 24 import java.io.OutputStream; |
22 | 25 |
23 class MyRfbProto extends RfbProto { | 26 class MyRfbProto extends RfbProto { |
24 | 27 |
25 final static String versionMsg_3_998 = "RFB 003.998\n"; | 28 final static String versionMsg_3_998 = "RFB 003.998\n"; |
26 | 29 |
27 | |
28 private int messageType; | 30 private int messageType; |
29 private int rectangles; | 31 private int rectangles; |
30 private int rectX; | 32 private int rectX; |
31 private int rectY; | 33 private int rectY; |
32 private int rectW; | 34 private int rectW; |
33 private int rectH; | 35 private int rectH; |
34 private int encoding; | 36 private int encoding; |
35 private int zLen; | 37 private int zLen; |
36 private int dataLen; | 38 private int dataLen; |
37 | 39 |
38 private ServerSocket servSock; | 40 private ServerSocket servSock; |
39 private int acceptPort; | 41 private int acceptPort; |
40 private byte initData[]; | 42 private byte initData[]; |
41 private LinkedList <Socket> cliListTmp; | 43 private LinkedList<Socket> cliListTmp; |
42 private LinkedList <Socket> cliList; | 44 private LinkedList<Socket> cliList; |
43 private LinkedList <Thread> sendThreads; | 45 private LinkedList<Thread> sendThreads; |
44 boolean createBimgFlag; | 46 boolean createBimgFlag; |
45 | |
46 echoClient echo; | |
47 | 47 |
48 ExecutorService executor; | 48 ExecutorService executor; |
49 | 49 |
50 | |
51 byte[] pngBytes; | 50 byte[] pngBytes; |
52 | 51 |
53 MyRfbProto(String h, int p, VncViewer v ) throws IOException { | 52 private MulticastQueue<byte[]> multicastqueue = new MulticastQueue<byte[]>(); |
53 | |
54 MyRfbProto(String h, int p, VncViewer v) throws IOException { | |
54 super(h, p, v); | 55 super(h, p, v); |
55 cliList = new LinkedList <Socket>(); | 56 cliList = new LinkedList<Socket>(); |
56 cliListTmp = new LinkedList <Socket>(); | 57 cliListTmp = new LinkedList<Socket>(); |
57 createBimgFlag = false; | 58 createBimgFlag = false; |
58 sendThreads = new LinkedList <Thread>(); | 59 sendThreads = new LinkedList<Thread>(); |
59 // executor = Executors.newCachedThreadPool(); | 60 // executor = Executors.newCachedThreadPool(); |
60 executor = Executors.newSingleThreadExecutor(); | 61 // executor = Executors.newSingleThreadExecutor(); |
61 } | 62 } |
62 | 63 |
63 MyRfbProto(String h, int p) throws IOException { | 64 MyRfbProto(String h, int p) throws IOException { |
64 super(h, p); | 65 super(h, p); |
65 cliList = new LinkedList <Socket>(); | 66 cliList = new LinkedList<Socket>(); |
66 cliListTmp = new LinkedList <Socket>(); | 67 cliListTmp = new LinkedList<Socket>(); |
67 createBimgFlag = false; | 68 createBimgFlag = false; |
68 sendThreads = new LinkedList <Thread>(); | 69 sendThreads = new LinkedList<Thread>(); |
69 // executor = Executors.newCachedThreadPool(); | 70 // executor = Executors.newCachedThreadPool(); |
70 executor = Executors.newSingleThreadExecutor(); | 71 // executor = Executors.newSingleThreadExecutor(); |
71 } | 72 } |
72 | 73 |
73 // over write | 74 // over write |
74 void writeVersionMsg() throws IOException { | 75 void writeVersionMsg() throws IOException { |
75 clientMajor = 3; | 76 clientMajor = 3; |
76 if (serverMinor >= 9) { | 77 if (serverMinor >= 9) { |
77 clientMinor = 9; | 78 clientMinor = 9; |
78 os.write(versionMsg_3_998.getBytes()); | 79 os.write(versionMsg_3_998.getBytes()); |
79 } else if (serverMajor > 3 || serverMinor >= 8) { | 80 } else if (serverMajor > 3 || serverMinor >= 8) { |
80 clientMinor = 8; | 81 clientMinor = 8; |
81 os.write(versionMsg_3_8.getBytes()); | 82 os.write(versionMsg_3_8.getBytes()); |
82 } else if (serverMinor >= 9) { | 83 } else if (serverMinor >= 9) { |
83 clientMinor = 9; | 84 clientMinor = 9; |
91 } | 92 } |
92 protocolTightVNC = false; | 93 protocolTightVNC = false; |
93 initCapabilities(); | 94 initCapabilities(); |
94 } | 95 } |
95 | 96 |
96 | 97 void initServSock(int port) throws IOException { |
97 | |
98 void initServSock(int port) throws IOException{ | |
99 servSock = new ServerSocket(port); | 98 servSock = new ServerSocket(port); |
100 acceptPort = port; | 99 acceptPort = port; |
101 } | 100 } |
102 void selectPort(){ | 101 |
102 // 5550を開けるが、開いてないなら+1のポートを開ける。 | |
103 void selectPort() { | |
103 int i = 5550; | 104 int i = 5550; |
104 while(true){ | 105 while (true) { |
105 try{ | 106 try { |
106 initServSock(i); | 107 initServSock(i); |
107 break; | 108 break; |
108 }catch(BindException e){ | 109 } catch (BindException e) { |
109 i++; | 110 i++; |
110 continue; | 111 continue; |
111 }catch(IOException e){ | 112 } catch (IOException e) { |
112 | 113 |
113 } | 114 } |
114 } | 115 } |
115 System.out.println("accept port = "+i); | 116 System.out.println("accept port = " + i); |
116 } | 117 } |
117 int getAcceptPort(){ | 118 |
119 int getAcceptPort() { | |
118 return acceptPort; | 120 return acceptPort; |
119 } | 121 } |
122 | |
120 void setSoTimeout(int num) throws IOException { | 123 void setSoTimeout(int num) throws IOException { |
121 servSock.setSoTimeout(num); | 124 servSock.setSoTimeout(num); |
122 } | 125 } |
123 | 126 |
124 Socket accept() throws IOException { | 127 Socket accept() throws IOException { |
125 return servSock.accept(); | 128 return servSock.accept(); |
126 } | 129 } |
127 | 130 |
128 void addSock(Socket sock){ | 131 void addSock(Socket sock) { |
129 cliList.add(sock); | 132 cliList.add(sock); |
130 } | 133 } |
131 void addSockTmp(Socket sock){ | 134 |
132 System.out.println("connected "+sock.getInetAddress()); | 135 void addSockTmp(Socket sock) { |
136 System.out.println("connected " + sock.getInetAddress()); | |
133 cliListTmp.add(sock); | 137 cliListTmp.add(sock); |
134 } | 138 } |
135 | |
136 void mark(int len) throws IOException { | |
137 is.mark(len); | |
138 } | |
139 | |
140 void reset() throws IOException { | |
141 is.reset(); | |
142 } | |
143 | 139 |
144 boolean markSupported() { | 140 boolean markSupported() { |
145 return is.markSupported(); | 141 return is.markSupported(); |
146 } | 142 } |
147 | 143 |
148 void readServerInit() throws IOException { | 144 void readServerInit() throws IOException { |
149 | 145 |
150 mark(255); | 146 is.mark(255); |
151 skipBytes(20); | 147 skipBytes(20); |
152 int nlen = readU32(); | 148 int nlen = readU32(); |
153 int blen = 20+4+nlen; | 149 int blen = 20 + 4 + nlen; |
154 initData = new byte[blen]; | 150 initData = new byte[blen]; |
155 reset(); | 151 is.reset(); |
156 | 152 |
157 mark(blen); | 153 is.mark(blen); |
158 readFully(initData); | 154 readFully(initData); |
159 reset(); | 155 is.reset(); |
160 | 156 |
161 framebufferWidth = readU16(); | 157 framebufferWidth = readU16(); |
162 framebufferHeight = readU16(); | 158 framebufferHeight = readU16(); |
163 bitsPerPixel = readU8(); | 159 bitsPerPixel = readU8(); |
164 depth = readU8(); | 160 depth = readU8(); |
165 bigEndian = (readU8() != 0); | 161 bigEndian = (readU8() != 0); |
189 } | 185 } |
190 | 186 |
191 inNormalProtocol = true; | 187 inNormalProtocol = true; |
192 } | 188 } |
193 | 189 |
194 void sendRfbVersion(OutputStream os) throws IOException{ | 190 void sendRfbVersion(OutputStream os) throws IOException { |
195 os.write(versionMsg_3_998.getBytes()); | 191 os.write(versionMsg_3_998.getBytes()); |
196 } | 192 } |
193 | |
197 void readVersionMsg(InputStream is) throws IOException { | 194 void readVersionMsg(InputStream is) throws IOException { |
198 | 195 |
199 byte[] b = new byte[12]; | 196 byte[] b = new byte[12]; |
200 | 197 |
201 is.read(b); | 198 is.read(b); |
213 serverMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0'); | 210 serverMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0'); |
214 | 211 |
215 if (serverMajor < 3) { | 212 if (serverMajor < 3) { |
216 throw new IOException( | 213 throw new IOException( |
217 "RFB server does not support protocol version 3"); | 214 "RFB server does not support protocol version 3"); |
218 } | 215 } |
219 | 216 |
220 } | 217 } |
218 | |
221 void sendSecurityType(OutputStream os) throws IOException { | 219 void sendSecurityType(OutputStream os) throws IOException { |
222 // number-of-security-types | 220 // number-of-security-types |
223 os.write(1); | 221 os.write(1); |
224 // security-types | 222 // security-types |
225 // 1:None | 223 // 1:None |
226 os.write(1); | 224 os.write(1); |
227 } | 225 } |
226 | |
228 void readSecType(InputStream is) throws IOException { | 227 void readSecType(InputStream is) throws IOException { |
229 byte[] b = new byte[1]; | 228 byte[] b = new byte[1]; |
230 is.read(b); | 229 is.read(b); |
231 | 230 |
232 } | 231 } |
232 | |
233 void sendSecResult(OutputStream os) throws IOException { | 233 void sendSecResult(OutputStream os) throws IOException { |
234 byte[] b = castIntByte(0); | 234 byte[] b = castIntByte(0); |
235 os.write(b); | 235 os.write(b); |
236 } | 236 } |
237 | 237 |
238 void readClientInit(InputStream in) throws IOException { | 238 void readClientInit(InputStream in) throws IOException { |
239 byte[] b = new byte[0]; | 239 byte[] b = new byte[0]; |
240 in.read(b); | 240 in.read(b); |
241 } | 241 } |
242 | 242 |
243 void sendInitData(OutputStream os) throws IOException{ | 243 void sendInitData(OutputStream os) throws IOException { |
244 os.write(initData); | 244 os.write(initData); |
245 } | 245 } |
246 | 246 |
247 void sendData(byte b[]){ | 247 void sendPngImage() { |
248 try{ | 248 try { |
249 for(Socket cli : cliList){ | 249 for (Socket cli : cliListTmp) { |
250 try{ | 250 try { |
251 cli.getOutputStream().write(b, 0, b.length); | |
252 }catch(IOException e){ | |
253 //insert | |
254 | |
255 System.out.println("lostchild"); | |
256 if("1".equals(echoClient.value.leaderflag)){ | |
257 echo = new echoClient(); | |
258 echo.openport(); | |
259 echo.lostchild(); | |
260 } | |
261 // if socket closed | |
262 cliList.remove(cli); | |
263 } | |
264 } | |
265 // System.out.println("cliSize="+cliSize()); | |
266 }catch(Exception e){ | |
267 } | |
268 } | |
269 | |
270 void sendPngImage(){ | |
271 try{ | |
272 for(Socket cli : cliListTmp){ | |
273 try{ | |
274 sendPngData(cli); | 251 sendPngData(cli); |
275 addSock(cli); | 252 addSock(cli); |
276 }catch(IOException e){ | 253 } catch (IOException e) { |
277 // if socket closed | 254 // if socket closed |
278 cliListTmp.remove(cli); | 255 cliListTmp.remove(cli); |
279 } | 256 } |
280 } | 257 } |
281 // System.out.println("cliSize="+cliSize()); | 258 // System.out.println("cliSize="+cliSize()); |
282 }catch(Exception e){ | 259 } catch (Exception e) { |
283 } | 260 } |
284 cliListTmp.clear(); | 261 cliListTmp.clear(); |
285 } | 262 } |
286 | |
287 | |
288 | 263 |
289 boolean ready() throws IOException { | 264 boolean ready() throws IOException { |
290 BufferedReader br = new BufferedReader(new InputStreamReader(is)); | 265 BufferedReader br = new BufferedReader(new InputStreamReader(is)); |
291 return br.ready(); | 266 return br.ready(); |
292 } | 267 } |
293 | 268 |
294 int cliSize(){ | 269 int cliSize() { |
295 return cliList.size(); | 270 return cliList.size(); |
296 } | 271 } |
297 void printNumBytesRead(){ | 272 |
298 System.out.println("numBytesRead="+numBytesRead); | 273 void printNumBytesRead() { |
299 } | 274 System.out.println("numBytesRead=" + numBytesRead); |
300 void bufResetSend(int size) throws IOException { | 275 } |
301 reset(); | 276 |
302 int len = size; | 277 void readSendData() throws IOException { |
303 if(available() < size ) | |
304 len = available(); | |
305 byte buffer[] = new byte[len]; | |
306 readFully(buffer); | |
307 sendData(buffer); | |
308 } | |
309 void readSendData()throws IOException{ | |
310 byte buffer[] = new byte[dataLen]; | 278 byte buffer[] = new byte[dataLen]; |
311 readFully(buffer); | 279 readFully(buffer); |
312 reset(); | 280 multicastqueue.put(buffer); |
313 | 281 is.reset(); |
314 for(Socket cli : cliList){ | 282 /* |
315 try{ | 283 |
284 for (Socket cli : cliList) { | |
285 try { | |
316 OutputStream out = cli.getOutputStream(); | 286 OutputStream out = cli.getOutputStream(); |
317 executor.execute(new SendThread(out, buffer)); | 287 executor.execute(new SendThread(out, buffer)); |
318 }catch(IOException e){ | 288 } catch (IOException e) { |
319 // if client socket closed | 289 // if client socket closed |
320 cliListTmp.remove(cli); | 290 cliListTmp.remove(cli); |
321 }catch(Exception e){ | 291 } catch (Exception e) { |
322 | 292 |
323 } | 293 } |
324 | 294 } |
325 } | 295 */ |
326 } | 296 } |
327 void regiFramebufferUpdate()throws IOException{ | 297 |
328 mark(20); | 298 void regiFramebufferUpdate() throws IOException { |
299 is.mark(20); | |
329 messageType = readU8(); | 300 messageType = readU8(); |
330 skipBytes(1); | 301 skipBytes(1); |
331 rectangles = readU16(); | 302 rectangles = readU16(); |
332 rectX = readU16(); | 303 rectX = readU16(); |
333 rectY = readU16(); | 304 rectY = readU16(); |
334 rectW = readU16(); | 305 rectW = readU16(); |
335 rectH = readU16(); | 306 rectH = readU16(); |
336 encoding = readU32(); | 307 encoding = readU32(); |
337 if(encoding == 16) | 308 if (encoding == 16) |
338 zLen = readU32(); | 309 zLen = readU32(); |
339 reset(); | 310 is.reset(); |
340 } | 311 } |
341 void checkAndMark() throws IOException{ | 312 |
342 switch(encoding){ | 313 void checkAndMark() throws IOException { |
314 switch (encoding) { | |
343 case RfbProto.EncodingRaw: | 315 case RfbProto.EncodingRaw: |
344 dataLen = rectW * rectH * 4 + 16; | 316 dataLen = rectW * rectH * 4 + 16; |
345 mark(dataLen); | 317 is.mark(dataLen); |
346 break; | 318 break; |
347 case RfbProto.EncodingZRLE: | 319 case RfbProto.EncodingZRLE: |
348 dataLen = zLen+20; | 320 dataLen = zLen + 20; |
349 mark(dataLen); | 321 is.mark(dataLen); |
350 break; | 322 break; |
351 default: | 323 default: |
352 mark(1000000); | 324 is.mark(1000000); |
353 } | 325 } |
354 } | 326 |
355 BufferedImage createBufferedImage(Image img){ | 327 } |
356 BufferedImage bimg = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB ); | 328 |
329 BufferedImage createBufferedImage(Image img) { | |
330 BufferedImage bimg = new BufferedImage(img.getWidth(null), | |
331 img.getHeight(null), BufferedImage.TYPE_INT_RGB); | |
357 | 332 |
358 Graphics g = bimg.getGraphics(); | 333 Graphics g = bimg.getGraphics(); |
359 g.drawImage(img, 0, 0, null); | 334 g.drawImage(img, 0, 0, null); |
360 g.dispose(); | 335 g.dispose(); |
361 return bimg; | 336 return bimg; |
362 } | 337 } |
363 | 338 |
364 void createPngBytes(BufferedImage bimg)throws IOException { | 339 void createPngBytes(BufferedImage bimg) throws IOException { |
365 pngBytes = getImageBytes(bimg , "png"); | 340 pngBytes = getImageBytes(bimg, "png"); |
366 } | 341 } |
367 byte[] getBytes(BufferedImage img)throws IOException { | 342 |
343 byte[] getBytes(BufferedImage img) throws IOException { | |
368 byte[] b = getImageBytes(img, "png"); | 344 byte[] b = getImageBytes(img, "png"); |
369 return b; | 345 return b; |
370 } | 346 } |
371 | 347 |
372 byte[] getImageBytes(BufferedImage image, String imageFormat) throws IOException { | 348 byte[] getImageBytes(BufferedImage image, String imageFormat) |
349 throws IOException { | |
373 ByteArrayOutputStream bos = new ByteArrayOutputStream(); | 350 ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
374 BufferedOutputStream os = new BufferedOutputStream(bos); | 351 BufferedOutputStream os = new BufferedOutputStream(bos); |
375 image.flush(); | 352 image.flush(); |
376 ImageIO.write(image, imageFormat, os); | 353 ImageIO.write(image, imageFormat, os); |
377 os.flush(); | 354 os.flush(); |
378 os.close(); | 355 os.close(); |
379 return bos.toByteArray(); | 356 return bos.toByteArray(); |
380 } | 357 } |
381 | 358 |
382 void sendPngData(Socket sock)throws IOException{ | 359 void sendPngData(Socket sock) throws IOException { |
383 byte[] dataLength = castIntByte(pngBytes.length); | 360 byte[] dataLength = castIntByte(pngBytes.length); |
384 sock.getOutputStream().write(dataLength); | 361 sock.getOutputStream().write(dataLength); |
385 sock.getOutputStream().write(pngBytes); | 362 sock.getOutputStream().write(pngBytes); |
386 } | 363 } |
387 byte[] castIntByte(int len){ | 364 |
365 byte[] castIntByte(int len) { | |
388 byte[] b = new byte[4]; | 366 byte[] b = new byte[4]; |
389 b[0] = (byte)((len >>> 24 ) & 0xFF); | 367 b[0] = (byte) ((len >>> 24) & 0xFF); |
390 b[1] = (byte)((len >>> 16 ) & 0xFF); | 368 b[1] = (byte) ((len >>> 16) & 0xFF); |
391 b[2] = (byte)((len >>> 8 ) & 0xFF); | 369 b[2] = (byte) ((len >>> 8) & 0xFF); |
392 b[3] = (byte)((len >>> 0 ) & 0xFF); | 370 b[3] = (byte) ((len >>> 0) & 0xFF); |
393 return b; | 371 return b; |
394 } | 372 } |
395 | 373 |
396 BufferedImage createBimg()throws IOException{ | 374 BufferedImage createBimg() throws IOException { |
397 BufferedImage bimg = ImageIO.read(new ByteArrayInputStream(pngBytes)); | 375 BufferedImage bimg = ImageIO.read(new ByteArrayInputStream(pngBytes)); |
398 return bimg; | 376 return bimg; |
399 } | 377 } |
400 void readPngData()throws IOException{ | 378 |
379 void readPngData() throws IOException { | |
401 pngBytes = new byte[is.available()]; | 380 pngBytes = new byte[is.available()]; |
402 readFully(pngBytes); | 381 readFully(pngBytes); |
403 } | 382 } |
404 void printFramebufferUpdate(){ | 383 |
405 | 384 void printFramebufferUpdate() { |
385 | |
406 System.out.println("messageType=" + messageType); | 386 System.out.println("messageType=" + messageType); |
407 System.out.println("rectangles="+rectangles); | 387 System.out.println("rectangles=" + rectangles); |
408 System.out.println("encoding=" + encoding); | 388 System.out.println("encoding=" + encoding); |
409 switch(encoding){ | 389 switch (encoding) { |
410 case RfbProto.EncodingRaw: | 390 case RfbProto.EncodingRaw: |
411 System.out.println("rectW * rectH * 4 + 16 =" + rectW * rectH * 4 + 16); | 391 System.out.println("rectW * rectH * 4 + 16 =" + rectW * rectH * 4 |
392 + 16); | |
412 break; | 393 break; |
413 default: | 394 default: |
414 } | 395 } |
415 } | 396 } |
397 | |
398 void newClient(acceptThread acceptThread, final Socket newCli, | |
399 final OutputStream os, final InputStream is) throws IOException { | |
400 // createBimgFlag = true; | |
401 // rfb.addSockTmp(newCli); | |
402 // addSock(newCli); | |
403 final Client<byte[]> c = multicastqueue.newClient(); | |
404 Runnable sender = new Runnable() { | |
405 @Override | |
406 public void run() { | |
407 try { | |
408 // 初期接続確立の部分 | |
409 sendRfbVersion(os); | |
410 readVersionMsg(is); | |
411 sendSecurityType(os); | |
412 readSecType(is); | |
413 sendSecResult(os); | |
414 readClientInit(is); | |
415 sendInitData(os); | |
416 | |
417 for (;;) { | |
418 byte[] b = c.poll(); | |
419 os.write(b, 0, b.length); | |
420 } | |
421 } catch (IOException e) { | |
422 //接続が切れた処理 | |
423 //lockしないと駄目 | |
424 // cliList.remove(newCli); | |
425 } | |
426 | |
427 } | |
428 | |
429 }; | |
430 new Thread(sender).start(); | |
431 | |
432 } | |
416 } | 433 } |
417 | |
418 |