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