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