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