Mercurial > hg > Members > nobuyasu > tightVNCClient
annotate src/myVncClient/MyVncClient.java @ 73:83acdeca0539
modify EchoClient
author | e085711 |
---|---|
date | Tue, 30 Aug 2011 06:59:57 +0900 |
parents | ec66d1d4dca0 |
children | 7d25b08f5835 |
rev | line source |
---|---|
20 | 1 package myVncClient; |
2 | |
3 import java.awt.*; | |
4 import java.awt.event.*; | |
5 import java.io.*; | |
6 import java.net.*; | |
41 | 7 import java.util.Random; |
20 | 8 |
73 | 9 import java.nio.ByteBuffer; |
10 | |
60 | 11 public class MyVncClient extends VncViewer implements InterfaceForViewer, java.lang.Runnable, |
32 | 12 WindowListener { |
20 | 13 |
50
c07bec8c8617
change echoClient.java EchoClient.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
49
diff
changeset
|
14 /** |
71 | 15 * |
50
c07bec8c8617
change echoClient.java EchoClient.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
49
diff
changeset
|
16 */ |
c07bec8c8617
change echoClient.java EchoClient.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
49
diff
changeset
|
17 private static final long serialVersionUID = 1L; |
20 | 18 boolean inAnApplet = true; |
19 boolean inSeparateFrame = false; | |
50
c07bec8c8617
change echoClient.java EchoClient.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
49
diff
changeset
|
20 Socket clientSocket = null; |
32 | 21 String parent, treenum; |
50
c07bec8c8617
change echoClient.java EchoClient.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
49
diff
changeset
|
22 private String leaderflag; |
55
f2f4b0398f04
update EchoClient.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
52
diff
changeset
|
23 boolean runflag = false; |
69 | 24 boolean first = true; |
72 | 25 |
26 EchoClient echovalue; | |
20 | 27 // |
28 // main() is called when run as a java program from the command line. | |
29 // It simply runs the applet inside a newly-created frame. | |
30 // | |
31 | |
60 | 32 public static void main(String[] argv) { |
51 | 33 MyVncClient v = new MyVncClient(); |
72 | 34 v.echovalue = null; |
51 | 35 v.runClient(argv); |
36 } | |
20 | 37 |
51 | 38 private void runClient(String[] argv) { |
39 mainArgs = argv; | |
35 | 40 inAnApplet = false; |
41 inSeparateFrame = true; | |
42 | |
73 | 43 host = mainArgs[0]; |
44 port = Integer.parseInt(mainArgs[1]); | |
45 | |
35 | 46 init(null); |
47 start_threads(); | |
48 start(); | |
20 | 49 } |
50 | |
51 // | |
52 // init() | |
53 // | |
54 | |
50
c07bec8c8617
change echoClient.java EchoClient.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
49
diff
changeset
|
55 public void init(EchoClient value) { |
60 | 56 |
73 | 57 readParameters(); |
72 | 58 // readParameters(); |
20 | 59 |
60 refApplet = this; | |
61 | |
62 if (inSeparateFrame) { | |
63 vncFrame = new Frame("TightVNC"); | |
64 if (!inAnApplet) { | |
65 vncFrame.add("Center", this); | |
66 } | |
67 vncContainer = vncFrame; | |
68 } else { | |
69 vncContainer = this; | |
70 } | |
71 | |
72 recordingSync = new Object(); | |
73 | |
74 options = new OptionsFrame(this); | |
75 clipboard = new ClipboardFrame(this); | |
76 if (RecordingFrame.checkSecurity()) | |
77 rec = new RecordingFrame(this); | |
78 | |
79 sessionFileName = null; | |
80 recordingActive = false; | |
81 recordingStatusChanged = false; | |
82 cursorUpdatesDef = null; | |
83 eightBitColorsDef = null; | |
84 | |
85 if (inSeparateFrame) | |
86 vncFrame.addWindowListener(this); | |
87 | |
88 rfbThread = new Thread(this); | |
89 } | |
90 | |
91 public void update(Graphics g) { | |
92 } | |
93 | |
94 // | |
95 // run() - executed by the rfbThread to deal with the RFB socket. | |
96 // | |
97 | |
60 | 98 public void start_threads() { |
33 | 99 rfbThread.start(); |
100 } | |
60 | 101 |
102 public void run() { | |
72 | 103 |
20 | 104 gridbag = new GridBagLayout(); |
105 vncContainer.setLayout(gridbag); | |
106 | |
107 GridBagConstraints gbc = new GridBagConstraints(); | |
108 gbc.gridwidth = GridBagConstraints.REMAINDER; | |
109 gbc.anchor = GridBagConstraints.NORTHWEST; | |
110 | |
111 if (showControls) { | |
112 buttonPanel = new ButtonPanel(this); | |
113 gridbag.setConstraints(buttonPanel, gbc); | |
114 vncContainer.add(buttonPanel); | |
115 } | |
60 | 116 |
20 | 117 try { |
118 | |
69 | 119 if (first) { |
71 | 120 connectAndAuthenticate(); |
70 | 121 accThread = new Thread(new AcceptThread(rfb, 5999)); |
122 accThread.start(); | |
69 | 123 first = false; |
124 }else { | |
70 | 125 System.out.println("reConnectAndAuthenticate() "); |
69 | 126 reConnectAndAuthenticate(); |
127 } | |
32 | 128 |
27 | 129 doProtocolInitialisation(); |
130 | |
20 | 131 createCanvas(0, 0); |
26 | 132 |
32 | 133 // rfb.readPngData(); |
134 // vc.drawFirstImage(); | |
20 | 135 |
136 } catch (IOException e) { | |
70 | 137 try{ |
138 rfb.sock.close(); | |
139 | |
140 }catch(IOException e2){ | |
141 e2.printStackTrace(); | |
142 } | |
20 | 143 System.out.println("Socket error"); |
41 | 144 // parent no find |
145 Random rnd = new Random(); | |
48
67655ba93e92
reconnection at connecton faild
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
46
diff
changeset
|
146 long ran = rnd.nextInt(5000) + 5000; |
67655ba93e92
reconnection at connecton faild
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
46
diff
changeset
|
147 System.out.println(ran); |
60 | 148 // 親がいない場合の処理はここに書く!!!! |
52 | 149 /** |
60 | 150 * this while reconnection |
52 | 151 */ |
60 | 152 |
55
f2f4b0398f04
update EchoClient.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
52
diff
changeset
|
153 int counter = 0; |
69 | 154 vncFrame.setVisible(false); |
155 vncFrame.dispose(); | |
156 | |
41 | 157 while (true) { |
52 | 158 /** |
60 | 159 * if my last node case reconnectoion stop |
52 | 160 */ |
60 | 161 |
162 echo = new EchoClient(echo, this); | |
41 | 163 try { |
164 Thread.sleep(ran); | |
60 | 165 } catch (InterruptedException e1) { |
41 | 166 e1.printStackTrace(); |
167 } | |
60 | 168 |
169 if (counter >= 3) { | |
55
f2f4b0398f04
update EchoClient.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
52
diff
changeset
|
170 echo.openport(); |
f2f4b0398f04
update EchoClient.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
52
diff
changeset
|
171 echo.notfoundParent(); |
f2f4b0398f04
update EchoClient.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
52
diff
changeset
|
172 } |
60 | 173 |
55
f2f4b0398f04
update EchoClient.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
52
diff
changeset
|
174 echo.openport(); |
60 | 175 // runflag = echo.losthost(); |
176 if (echo.losthost()) { | |
52 | 177 break; |
178 } | |
55
f2f4b0398f04
update EchoClient.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
52
diff
changeset
|
179 counter++; |
41 | 180 } |
69 | 181 |
41 | 182 // System.exit(0); |
32 | 183 } catch (Exception e) { |
33 | 184 System.out.println(e); |
41 | 185 System.exit(0); |
20 | 186 } |
187 | |
188 gbc.weightx = 1.0; | |
189 gbc.weighty = 1.0; | |
190 | |
32 | 191 if (inSeparateFrame) { |
20 | 192 |
193 // Create a panel which itself is resizeable and can hold | |
194 // non-resizeable VncCanvas component at the top left corner. | |
195 Panel canvasPanel = new Panel(); | |
196 canvasPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); | |
197 canvasPanel.add(vc); | |
198 | |
199 // Create a ScrollPane which will hold a panel with VncCanvas | |
200 // inside. | |
201 desktopScrollPane = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED); | |
202 gbc.fill = GridBagConstraints.BOTH; | |
203 gridbag.setConstraints(desktopScrollPane, gbc); | |
204 desktopScrollPane.add(canvasPanel); | |
205 | |
206 // Finally, add our ScrollPane to the Frame window. | |
207 vncFrame.add(desktopScrollPane); | |
208 vncFrame.setTitle(rfb.desktopName); | |
209 vncFrame.pack(); | |
210 vc.resizeDesktopFrame(); | |
211 | |
212 } else { | |
213 | |
214 // Just add the VncCanvas component to the Applet. | |
215 gridbag.setConstraints(vc, gbc); | |
216 add(vc); | |
217 validate(); | |
218 | |
219 } | |
220 | |
221 try { | |
222 if (showControls) | |
223 buttonPanel.enableButtons(); | |
224 | |
225 moveFocusToDesktop(); | |
226 | |
227 processNormalProtocol();// main loop | |
228 | |
229 } catch (NoRouteToHostException e) { | |
230 fatalError("Network error: no route to server: " + host, e); | |
231 } catch (UnknownHostException e) { | |
232 fatalError("Network error: server name unknown: " + host, e); | |
233 } catch (ConnectException e) { | |
234 fatalError("Network error: could not connect to server: " + host | |
235 + ":" + port, e); | |
236 } catch (EOFException e) { | |
70 | 237 |
34 | 238 vncFrame.setVisible(false); |
65 | 239 vncFrame.dispose(); |
60 | 240 // num4 |
32 | 241 // リーダーの子ノードがproxyに対して親が落ちたことを報告をする |
60 | 242 if (leaderflag != null) { |
243 while (true) { | |
244 echo = new EchoClient(echo, this); | |
55
f2f4b0398f04
update EchoClient.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
52
diff
changeset
|
245 echo.openport(); |
60 | 246 // runflag = echo.losthost(); |
247 if (echo.losthost()) { | |
55
f2f4b0398f04
update EchoClient.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
52
diff
changeset
|
248 break; |
f2f4b0398f04
update EchoClient.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
52
diff
changeset
|
249 } |
f2f4b0398f04
update EchoClient.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
52
diff
changeset
|
250 } |
32 | 251 } else { |
29
750ecaa1e1b9
add echoClient.java and waitreply.java. modify MyRfbProto.java
e085711
parents:
27
diff
changeset
|
252 |
32 | 253 if (showOfflineDesktop) { |
254 e.printStackTrace(); | |
255 System.out | |
256 .println("Network error: remote side closed connection"); | |
257 if (vc != null) { | |
258 vc.enableInput(false); | |
259 } | |
260 if (inSeparateFrame) { | |
261 vncFrame.setTitle(rfb.desktopName + " [disconnected]"); | |
262 } | |
263 if (rfb != null && !rfb.closed()) | |
264 rfb.close(); | |
265 if (showControls && buttonPanel != null) { | |
266 buttonPanel.disableButtonsOnDisconnect(); | |
267 if (inSeparateFrame) { | |
268 vncFrame.pack(); | |
269 } else { | |
270 validate(); | |
271 } | |
272 } | |
273 } else { | |
274 fatalError("Network error: remote side closed connection", | |
275 e); | |
20 | 276 } |
277 } | |
278 } catch (IOException e) { | |
279 String str = e.getMessage(); | |
280 if (str != null && str.length() != 0) { | |
281 fatalError("Network Error: " + str, e); | |
282 } else { | |
283 fatalError(e.toString(), e); | |
284 } | |
285 } catch (Exception e) { | |
286 String str = e.getMessage(); | |
287 if (str != null && str.length() != 0) { | |
288 fatalError("Error: " + str, e); | |
289 } else { | |
290 fatalError(e.toString(), e); | |
291 } | |
292 } | |
293 | |
294 } | |
295 | |
296 // | |
297 // Create a VncCanvas instance. | |
298 // | |
299 | |
300 void createCanvas(int maxWidth, int maxHeight) throws IOException { | |
301 // Determine if Java 2D API is available and use a special | |
302 // version of VncCanvas if it is present. | |
303 vc = null; | |
304 try { | |
305 // This throws ClassNotFoundException if there is no Java 2D API. | |
306 Class cl = Class.forName("java.awt.Graphics2D"); | |
307 // If we could load Graphics2D class, then we can use VncCanvas2D. | |
308 cl = Class.forName("VncCanvas2"); | |
309 Class[] argClasses = { this.getClass(), Integer.TYPE, Integer.TYPE }; | |
310 java.lang.reflect.Constructor cstr = cl.getConstructor(argClasses); | |
311 Object[] argObjects = { this, new Integer(maxWidth), | |
312 new Integer(maxHeight) }; | |
313 vc = (VncCanvas) cstr.newInstance(argObjects); | |
314 } catch (Exception e) { | |
315 System.out.println("Warning: Java 2D API is not available"); | |
316 } | |
317 | |
318 // If we failed to create VncCanvas2D, use old VncCanvas. | |
319 if (vc == null) | |
320 vc = new VncCanvas(this, maxWidth, maxHeight); | |
321 } | |
322 | |
323 // | |
324 // Process RFB socket messages. | |
325 // If the rfbThread is being stopped, ignore any exceptions, | |
326 // otherwise rethrow the exception so it can be handled. | |
327 // | |
328 | |
329 void processNormalProtocol() throws Exception { | |
330 try { | |
331 vc.processNormalProtocol();// main loop | |
332 } catch (Exception e) { | |
333 if (rfbThread == null) { | |
334 System.out.println("Ignoring RFB socket exceptions" | |
335 + " because applet is stopping"); | |
336 } else { | |
337 throw e; | |
338 } | |
339 } | |
340 } | |
341 | |
342 // | |
343 // Connect to the RFB server and authenticate the user. | |
344 // | |
345 | |
346 void connectAndAuthenticate() throws Exception { | |
27 | 347 |
20 | 348 showConnectionStatus("Initializing..."); |
349 if (inSeparateFrame) { | |
350 vncFrame.pack(); | |
351 vncFrame.setVisible(true); | |
352 } else { | |
353 validate(); | |
354 } | |
355 | |
356 showConnectionStatus("Connecting to " + host + ", port " + port + "..."); | |
357 | |
358 rfb = new MyRfbProto(host, port, this); | |
359 showConnectionStatus("Connected to server"); | |
360 | |
361 rfb.readVersionMsg(); | |
362 showConnectionStatus("RFB server supports protocol version " | |
363 + rfb.serverMajor + "." + rfb.serverMinor); | |
364 | |
73 | 365 rfb.writeVersionMsg(); |
366 showConnectionStatus("Using RFB protocol version " + rfb.clientMajor | |
367 + "." + rfb.clientMinor); | |
368 | |
72 | 369 if(rfb.serverMinor == 998) { |
73 | 370 byte[] b = new byte[4]; |
371 b = rfb.readEchoPort(); | |
372 int echoPort = castByteInt(b); | |
72 | 373 String h = host; |
73 | 374 getParentname(echovalue, echoPort); |
72 | 375 if(h.equals(host)) { |
376 rfb.changeParent(host, port); | |
377 rfb.readVersionMsg(); | |
378 } | |
379 } | |
380 | |
381 | |
20 | 382 int secType = rfb.negotiateSecurity(); |
383 int authType; | |
384 if (secType == RfbProto.SecTypeTight) { | |
385 showConnectionStatus("Enabling TightVNC protocol extensions"); | |
386 rfb.setupTunneling(); | |
387 authType = rfb.negotiateAuthenticationTight(); | |
388 } else { | |
389 authType = secType; | |
390 } | |
391 | |
392 switch (authType) { | |
393 case RfbProto.AuthNone: | |
394 showConnectionStatus("No authentication needed"); | |
395 rfb.authenticateNone(); | |
396 break; | |
397 case RfbProto.AuthVNC: | |
398 showConnectionStatus("Performing standard VNC authentication"); | |
399 if (passwordParam != null) { | |
400 rfb.authenticateVNC(passwordParam); | |
401 } else { | |
402 String pw = askPassword(); | |
403 rfb.authenticateVNC(pw); | |
404 } | |
405 break; | |
406 default: | |
407 throw new Exception("Unknown authentication scheme " + authType); | |
408 } | |
409 } | |
410 | |
69 | 411 void reConnectAndAuthenticate() throws Exception { |
71 | 412 |
69 | 413 showConnectionStatus("Initializing..."); |
414 | |
71 | 415 if (inSeparateFrame) { |
416 vncFrame.pack(); | |
417 vncFrame.setVisible(true); | |
418 } else { | |
419 validate(); | |
420 } | |
421 | |
69 | 422 showConnectionStatus("Connecting to " + host + ", port " + port + "..."); |
423 | |
424 rfb.changeParent(host, port); | |
425 | |
426 showConnectionStatus("Connected to server"); | |
427 | |
428 rfb.readVersionMsg(); | |
429 showConnectionStatus("RFB server supports protocol version " | |
430 + rfb.serverMajor + "." + rfb.serverMinor); | |
431 | |
432 rfb.writeVersionMsg(); | |
433 showConnectionStatus("Using RFB protocol version " + rfb.clientMajor | |
434 + "." + rfb.clientMinor); | |
435 | |
436 int secType = rfb.negotiateSecurity(); | |
437 int authType; | |
438 if (secType == RfbProto.SecTypeTight) { | |
439 showConnectionStatus("Enabling TightVNC protocol extensions"); | |
440 rfb.setupTunneling(); | |
441 authType = rfb.negotiateAuthenticationTight(); | |
442 } else { | |
443 authType = secType; | |
444 } | |
445 | |
446 switch (authType) { | |
447 case RfbProto.AuthNone: | |
448 showConnectionStatus("No authentication needed"); | |
449 rfb.authenticateNone(); | |
450 break; | |
451 case RfbProto.AuthVNC: | |
452 showConnectionStatus("Performing standard VNC authentication"); | |
453 if (passwordParam != null) { | |
454 rfb.authenticateVNC(passwordParam); | |
455 } else { | |
456 String pw = askPassword(); | |
457 rfb.authenticateVNC(pw); | |
458 } | |
459 break; | |
460 default: | |
461 throw new Exception("Unknown authentication scheme " + authType); | |
462 } | |
463 } | |
20 | 464 // |
465 // Show a message describing the connection status. | |
466 // To hide the connection status label, use (msg == null). | |
467 // | |
468 | |
469 void showConnectionStatus(String msg) { | |
470 if (msg == null) { | |
471 if (vncContainer.isAncestorOf(connStatusLabel)) { | |
472 vncContainer.remove(connStatusLabel); | |
473 } | |
474 return; | |
475 } | |
476 | |
477 System.out.println(msg); | |
478 | |
479 if (connStatusLabel == null) { | |
480 connStatusLabel = new Label("Status: " + msg); | |
481 connStatusLabel.setFont(new Font("Helvetica", Font.PLAIN, 12)); | |
482 } else { | |
483 connStatusLabel.setText("Status: " + msg); | |
484 } | |
485 | |
486 if (!vncContainer.isAncestorOf(connStatusLabel)) { | |
487 GridBagConstraints gbc = new GridBagConstraints(); | |
488 gbc.gridwidth = GridBagConstraints.REMAINDER; | |
489 gbc.fill = GridBagConstraints.HORIZONTAL; | |
490 gbc.anchor = GridBagConstraints.NORTHWEST; | |
491 gbc.weightx = 1.0; | |
492 gbc.weighty = 1.0; | |
493 gbc.insets = new Insets(20, 30, 20, 30); | |
494 gridbag.setConstraints(connStatusLabel, gbc); | |
495 vncContainer.add(connStatusLabel); | |
496 } | |
497 | |
498 if (inSeparateFrame) { | |
499 vncFrame.pack(); | |
500 } else { | |
501 validate(); | |
502 } | |
503 } | |
504 | |
505 // | |
506 // Show an authentication panel. | |
507 // | |
508 | |
509 String askPassword() throws Exception { | |
510 showConnectionStatus(null); | |
511 | |
512 AuthPanel authPanel = new AuthPanel(this); | |
513 | |
514 GridBagConstraints gbc = new GridBagConstraints(); | |
515 gbc.gridwidth = GridBagConstraints.REMAINDER; | |
516 gbc.anchor = GridBagConstraints.NORTHWEST; | |
517 gbc.weightx = 1.0; | |
518 gbc.weighty = 1.0; | |
519 gbc.ipadx = 100; | |
520 gbc.ipady = 50; | |
521 gridbag.setConstraints(authPanel, gbc); | |
522 vncContainer.add(authPanel); | |
523 | |
524 if (inSeparateFrame) { | |
525 vncFrame.pack(); | |
526 } else { | |
527 validate(); | |
528 } | |
529 | |
530 authPanel.moveFocusToDefaultField(); | |
531 String pw = authPanel.getPassword(); | |
532 vncContainer.remove(authPanel); | |
533 return pw; | |
534 } | |
535 | |
536 // | |
537 // Do the rest of the protocol initialisation. | |
538 // | |
539 | |
540 void doProtocolInitialisation() throws IOException { | |
541 rfb.writeClientInit(); | |
542 rfb.readServerInit(); | |
543 | |
544 System.out.println("Desktop name is " + rfb.desktopName); | |
545 System.out.println("Desktop size is " + rfb.framebufferWidth + " x " | |
546 + rfb.framebufferHeight); | |
547 | |
548 setEncodings(); | |
549 | |
550 showConnectionStatus(null); | |
551 } | |
552 | |
553 // | |
554 // Send current encoding list to the RFB server. | |
555 // | |
556 | |
557 int[] encodingsSaved; | |
558 int nEncodingsSaved; | |
559 | |
560 void setEncodings() { | |
561 setEncodings(false); | |
562 } | |
563 | |
564 void autoSelectEncodings() { | |
565 setEncodings(true); | |
566 } | |
567 | |
568 void setEncodings(boolean autoSelectOnly) { | |
569 if (options == null || rfb == null || !rfb.inNormalProtocol) | |
570 return; | |
571 | |
572 int preferredEncoding = options.preferredEncoding; | |
573 if (preferredEncoding == -1) { | |
574 long kbitsPerSecond = rfb.kbitsPerSecond(); | |
575 if (nEncodingsSaved < 1) { | |
576 // Choose Tight or ZRLE encoding for the very first update. | |
577 System.out.println("Using Tight/ZRLE encodings"); | |
578 preferredEncoding = RfbProto.EncodingTight; | |
579 } else if (kbitsPerSecond > 2000 | |
580 && encodingsSaved[0] != RfbProto.EncodingHextile) { | |
581 // Switch to Hextile if the connection speed is above 2Mbps. | |
582 System.out.println("Throughput " + kbitsPerSecond | |
583 + " kbit/s - changing to Hextile encoding"); | |
584 preferredEncoding = RfbProto.EncodingHextile; | |
585 } else if (kbitsPerSecond < 1000 | |
586 && encodingsSaved[0] != RfbProto.EncodingTight) { | |
587 // Switch to Tight/ZRLE if the connection speed is below 1Mbps. | |
588 System.out.println("Throughput " + kbitsPerSecond | |
589 + " kbit/s - changing to Tight/ZRLE encodings"); | |
590 preferredEncoding = RfbProto.EncodingTight; | |
591 } else { | |
592 // Don't change the encoder. | |
593 if (autoSelectOnly) | |
594 return; | |
595 preferredEncoding = encodingsSaved[0]; | |
596 } | |
597 } else { | |
598 // Auto encoder selection is not enabled. | |
599 if (autoSelectOnly) | |
600 return; | |
601 } | |
602 | |
603 int[] encodings = new int[20]; | |
604 int nEncodings = 0; | |
605 | |
606 encodings[nEncodings++] = preferredEncoding; | |
607 if (options.useCopyRect) { | |
608 encodings[nEncodings++] = RfbProto.EncodingCopyRect; | |
609 } | |
610 | |
611 if (preferredEncoding != RfbProto.EncodingTight) { | |
612 encodings[nEncodings++] = RfbProto.EncodingTight; | |
613 } | |
614 if (preferredEncoding != RfbProto.EncodingZRLE) { | |
615 encodings[nEncodings++] = RfbProto.EncodingZRLE; | |
616 } | |
617 if (preferredEncoding != RfbProto.EncodingHextile) { | |
618 encodings[nEncodings++] = RfbProto.EncodingHextile; | |
619 } | |
620 if (preferredEncoding != RfbProto.EncodingZlib) { | |
621 encodings[nEncodings++] = RfbProto.EncodingZlib; | |
622 } | |
623 if (preferredEncoding != RfbProto.EncodingCoRRE) { | |
624 encodings[nEncodings++] = RfbProto.EncodingCoRRE; | |
625 } | |
626 if (preferredEncoding != RfbProto.EncodingRRE) { | |
627 encodings[nEncodings++] = RfbProto.EncodingRRE; | |
628 } | |
629 | |
630 if (options.compressLevel >= 0 && options.compressLevel <= 9) { | |
631 encodings[nEncodings++] = RfbProto.EncodingCompressLevel0 | |
632 + options.compressLevel; | |
633 } | |
634 if (options.jpegQuality >= 0 && options.jpegQuality <= 9) { | |
635 encodings[nEncodings++] = RfbProto.EncodingQualityLevel0 | |
636 + options.jpegQuality; | |
637 } | |
638 | |
639 if (options.requestCursorUpdates) { | |
640 encodings[nEncodings++] = RfbProto.EncodingXCursor; | |
641 encodings[nEncodings++] = RfbProto.EncodingRichCursor; | |
642 if (!options.ignoreCursorUpdates) | |
643 encodings[nEncodings++] = RfbProto.EncodingPointerPos; | |
644 } | |
645 | |
646 encodings[nEncodings++] = RfbProto.EncodingLastRect; | |
647 encodings[nEncodings++] = RfbProto.EncodingNewFBSize; | |
648 | |
649 boolean encodingsWereChanged = false; | |
650 if (nEncodings != nEncodingsSaved) { | |
651 encodingsWereChanged = true; | |
652 } else { | |
653 for (int i = 0; i < nEncodings; i++) { | |
654 if (encodings[i] != encodingsSaved[i]) { | |
655 encodingsWereChanged = true; | |
656 break; | |
657 } | |
658 } | |
659 } | |
660 | |
661 if (encodingsWereChanged) { | |
662 try { | |
663 rfb.writeSetEncodings(encodings, nEncodings); | |
664 if (vc != null) { | |
665 vc.softCursorFree(); | |
666 } | |
667 } catch (Exception e) { | |
668 e.printStackTrace(); | |
669 } | |
670 encodingsSaved = encodings; | |
671 nEncodingsSaved = nEncodings; | |
672 } | |
673 } | |
674 | |
675 // | |
676 // setCutText() - send the given cut text to the RFB server. | |
677 // | |
678 | |
679 void setCutText(String text) { | |
680 try { | |
681 if (rfb != null && rfb.inNormalProtocol) { | |
682 rfb.writeClientCutText(text); | |
683 } | |
684 } catch (Exception e) { | |
685 e.printStackTrace(); | |
686 } | |
687 } | |
688 | |
689 // | |
690 // Order change in session recording status. To stop recording, pass | |
691 // null in place of the fname argument. | |
692 // | |
693 | |
694 void setRecordingStatus(String fname) { | |
695 synchronized (recordingSync) { | |
696 sessionFileName = fname; | |
697 recordingStatusChanged = true; | |
698 } | |
699 } | |
700 | |
701 // | |
702 // Start or stop session recording. Returns true if this method call | |
703 // causes recording of a new session. | |
704 // | |
705 | |
706 boolean checkRecordingStatus() throws IOException { | |
707 synchronized (recordingSync) { | |
708 if (recordingStatusChanged) { | |
709 recordingStatusChanged = false; | |
710 if (sessionFileName != null) { | |
711 startRecording(); | |
712 return true; | |
713 } else { | |
714 stopRecording(); | |
715 } | |
716 } | |
717 } | |
718 return false; | |
719 } | |
720 | |
721 // | |
722 // Start session recording. | |
723 // | |
724 | |
725 protected void startRecording() throws IOException { | |
726 synchronized (recordingSync) { | |
727 if (!recordingActive) { | |
728 // Save settings to restore them after recording the session. | |
729 cursorUpdatesDef = options.choices[options.cursorUpdatesIndex] | |
730 .getSelectedItem(); | |
731 eightBitColorsDef = options.choices[options.eightBitColorsIndex] | |
732 .getSelectedItem(); | |
733 // Set options to values suitable for recording. | |
734 options.choices[options.cursorUpdatesIndex].select("Disable"); | |
735 options.choices[options.cursorUpdatesIndex].setEnabled(false); | |
736 options.setEncodings(); | |
737 options.choices[options.eightBitColorsIndex].select("No"); | |
738 options.choices[options.eightBitColorsIndex].setEnabled(false); | |
739 options.setColorFormat(); | |
740 } else { | |
741 rfb.closeSession(); | |
742 } | |
743 | |
744 System.out.println("Recording the session in " + sessionFileName); | |
745 rfb.startSession(sessionFileName); | |
746 recordingActive = true; | |
747 } | |
748 } | |
749 | |
750 // | |
751 // Stop session recording. | |
752 // | |
753 | |
754 protected void stopRecording() throws IOException { | |
755 synchronized (recordingSync) { | |
756 if (recordingActive) { | |
757 // Restore options. | |
758 options.choices[options.cursorUpdatesIndex] | |
759 .select(cursorUpdatesDef); | |
760 options.choices[options.cursorUpdatesIndex].setEnabled(true); | |
761 options.setEncodings(); | |
762 options.choices[options.eightBitColorsIndex] | |
763 .select(eightBitColorsDef); | |
764 options.choices[options.eightBitColorsIndex].setEnabled(true); | |
765 options.setColorFormat(); | |
766 | |
767 rfb.closeSession(); | |
768 System.out.println("Session recording stopped."); | |
769 } | |
770 sessionFileName = null; | |
771 recordingActive = false; | |
772 } | |
773 } | |
774 | |
35 | 775 /** |
60 | 776 * readParameters() - read parameters from the html source or from the |
777 * command line. On the command line, the arguments are just a sequence of | |
778 * param_name/param_value pairs where the names and values correspond to | |
779 * those expected in the html applet tag source. | |
780 */ | |
20 | 781 |
73 | 782 void readParameters() { |
32 | 783 /* |
784 * host = readParameter("HOST", !inAnApplet); | |
785 * | |
786 * if (host == null) { host = getCodeBase().getHost(); if | |
787 * (host.equals("")) { fatalError("HOST parameter not specified"); } } | |
788 * | |
789 * port = readIntParameter("PORT", 5550); | |
790 */ | |
72 | 791 |
30 | 792 // Read "ENCPASSWORD" or "PASSWORD" parameter if specified. |
20 | 793 readPasswordParameters(); |
794 | |
795 String str; | |
796 if (inAnApplet) { | |
797 str = readParameter("Open New Window", false); | |
798 if (str != null && str.equalsIgnoreCase("Yes")) | |
799 inSeparateFrame = true; | |
800 } | |
801 | |
802 // "Show Controls" set to "No" disables button panel. | |
803 showControls = true; | |
804 str = readParameter("Show Controls", false); | |
805 if (str != null && str.equalsIgnoreCase("No")) | |
806 showControls = false; | |
807 | |
808 // "Offer Relogin" set to "No" disables "Login again" and "Close | |
809 // window" buttons under error messages in applet mode. | |
810 offerRelogin = true; | |
811 str = readParameter("Offer Relogin", false); | |
812 if (str != null && str.equalsIgnoreCase("No")) | |
813 offerRelogin = false; | |
814 | |
815 // Do we continue showing desktop on remote disconnect? | |
816 showOfflineDesktop = false; | |
817 str = readParameter("Show Offline Desktop", false); | |
818 if (str != null && str.equalsIgnoreCase("Yes")) | |
819 showOfflineDesktop = true; | |
820 | |
821 // Fine tuning options. | |
822 deferScreenUpdates = readIntParameter("Defer screen updates", 20); | |
823 deferCursorUpdates = readIntParameter("Defer cursor updates", 10); | |
824 deferUpdateRequests = readIntParameter("Defer update requests", 0); | |
825 | |
826 // Debugging options. | |
827 debugStatsExcludeUpdates = readIntParameter("DEBUG_XU", 0); | |
828 debugStatsMeasureUpdates = readIntParameter("DEBUG_CU", 0); | |
829 | |
830 // SocketFactory. | |
831 socketFactory = readParameter("SocketFactory", false); | |
832 } | |
833 | |
834 // | |
835 // Read password parameters. If an "ENCPASSWORD" parameter is set, | |
836 // then decrypt the password into the passwordParam string. Otherwise, | |
837 // try to read the "PASSWORD" parameter directly to passwordParam. | |
838 // | |
839 | |
840 private void readPasswordParameters() { | |
841 String encPasswordParam = readParameter("ENCPASSWORD", false); | |
842 if (encPasswordParam == null) { | |
843 passwordParam = readParameter("PASSWORD", false); | |
844 | |
845 } else { | |
846 // ENCPASSWORD is hexascii-encoded. Decode. | |
847 byte[] pw = { 0, 0, 0, 0, 0, 0, 0, 0 }; | |
848 int len = encPasswordParam.length() / 2; | |
849 if (len > 8) | |
850 len = 8; | |
851 for (int i = 0; i < len; i++) { | |
852 String hex = encPasswordParam.substring(i * 2, i * 2 + 2); | |
853 Integer x = new Integer(Integer.parseInt(hex, 16)); | |
854 pw[i] = x.byteValue(); | |
855 } | |
856 // Decrypt the password. | |
857 byte[] key = { 23, 82, 107, 6, 35, 78, 88, 7 }; | |
858 DesCipher des = new DesCipher(key); | |
859 des.decrypt(pw, 0, pw, 0); | |
860 passwordParam = new String(pw); | |
861 | |
862 } | |
863 } | |
864 | |
865 public String readParameter(String name, boolean required) { | |
866 if (inAnApplet) { | |
867 String s = getParameter(name); | |
868 if ((s == null) && required) { | |
869 fatalError(name + " parameter not specified"); | |
870 } | |
871 return s; | |
872 } | |
60 | 873 /* |
874 * for (int i = 0; i < mainArgs.length; i += 2) { if | |
875 * (mainArgs[i].equalsIgnoreCase(name)) { try { return mainArgs[i + 1]; | |
876 * } catch (Exception e) { if (required) { fatalError(name + | |
877 * " parameter not specified"); } return null; } } } | |
878 */ | |
20 | 879 if (required) { |
880 fatalError(name + " parameter not specified"); | |
881 } | |
882 return null; | |
883 } | |
884 | |
885 int readIntParameter(String name, int defaultValue) { | |
886 String str = readParameter(name, false); | |
887 int result = defaultValue; | |
888 if (str != null) { | |
889 try { | |
890 result = Integer.parseInt(str); | |
891 } catch (NumberFormatException e) { | |
892 } | |
893 } | |
894 return result; | |
895 } | |
896 | |
897 // | |
898 // moveFocusToDesktop() - move keyboard focus either to VncCanvas. | |
899 // | |
900 | |
901 void moveFocusToDesktop() { | |
902 if (vncContainer != null) { | |
903 if (vc != null && vncContainer.isAncestorOf(vc)) | |
904 vc.requestFocus(); | |
905 } | |
906 } | |
907 | |
908 // | |
909 // disconnect() - close connection to server. | |
910 // | |
911 | |
912 synchronized public void disconnect() { | |
913 System.out.println("Disconnecting"); | |
914 | |
915 if (vc != null) { | |
916 double sec = (System.currentTimeMillis() - vc.statStartTime) / 1000.0; | |
917 double rate = Math.round(vc.statNumUpdates / sec * 100) / 100.0; | |
918 int nRealRects = vc.statNumPixelRects; | |
919 int nPseudoRects = vc.statNumTotalRects - vc.statNumPixelRects; | |
920 System.out.println("Updates received: " + vc.statNumUpdates + " (" | |
921 + nRealRects + " rectangles + " + nPseudoRects | |
922 + " pseudo), " + rate + " updates/sec"); | |
923 int numRectsOther = nRealRects - vc.statNumRectsTight | |
924 - vc.statNumRectsZRLE - vc.statNumRectsHextile | |
925 - vc.statNumRectsRaw - vc.statNumRectsCopy; | |
926 System.out.println("Rectangles:" + " Tight=" + vc.statNumRectsTight | |
927 + "(JPEG=" + vc.statNumRectsTightJPEG + ") ZRLE=" | |
928 + vc.statNumRectsZRLE + " Hextile=" | |
929 + vc.statNumRectsHextile + " Raw=" + vc.statNumRectsRaw | |
930 + " CopyRect=" + vc.statNumRectsCopy + " other=" | |
931 + numRectsOther); | |
932 | |
933 int raw = vc.statNumBytesDecoded; | |
934 int compressed = vc.statNumBytesEncoded; | |
935 if (compressed > 0) { | |
936 double ratio = Math.round((double) raw / compressed * 1000) / 1000.0; | |
937 System.out.println("Pixel data: " + vc.statNumBytesDecoded | |
938 + " bytes, " + vc.statNumBytesEncoded | |
939 + " compressed, ratio " + ratio); | |
940 } | |
941 } | |
942 | |
943 if (rfb != null && !rfb.closed()) | |
944 rfb.close(); | |
945 options.dispose(); | |
946 clipboard.dispose(); | |
947 if (rec != null) | |
948 rec.dispose(); | |
949 | |
950 if (inAnApplet) { | |
951 showMessage("Disconnected"); | |
952 } else { | |
953 System.exit(0); | |
954 } | |
955 } | |
956 | |
957 // | |
958 // fatalError() - print out a fatal error message. | |
959 // FIXME: Do we really need two versions of the fatalError() method? | |
960 // | |
961 | |
962 synchronized public void fatalError(String str) { | |
963 System.out.println(str); | |
964 | |
965 if (inAnApplet) { | |
966 // vncContainer null, applet not inited, | |
967 // can not present the error to the user. | |
968 Thread.currentThread().stop(); | |
969 } else { | |
970 System.exit(1); | |
971 } | |
972 } | |
973 | |
974 synchronized public void fatalError(String str, Exception e) { | |
975 | |
976 if (rfb != null && rfb.closed()) { | |
977 // Not necessary to show error message if the error was caused | |
978 // by I/O problems after the rfb.close() method call. | |
979 System.out.println("RFB thread finished"); | |
980 return; | |
981 } | |
982 | |
983 System.out.println(str); | |
984 e.printStackTrace(); | |
985 | |
986 if (rfb != null) | |
987 rfb.close(); | |
988 | |
989 if (inAnApplet) { | |
990 showMessage(str); | |
991 } else { | |
992 System.exit(1); | |
993 } | |
994 } | |
60 | 995 |
20 | 996 // |
997 // Show message text and optionally "Relogin" and "Close" buttons. | |
998 // | |
999 | |
1000 void showMessage(String msg) { | |
1001 vncContainer.removeAll(); | |
1002 | |
1003 Label errLabel = new Label(msg, Label.CENTER); | |
1004 errLabel.setFont(new Font("Helvetica", Font.PLAIN, 12)); | |
1005 | |
1006 if (offerRelogin) { | |
1007 | |
1008 Panel gridPanel = new Panel(new GridLayout(0, 1)); | |
1009 Panel outerPanel = new Panel(new FlowLayout(FlowLayout.LEFT)); | |
1010 outerPanel.add(gridPanel); | |
1011 vncContainer.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 16)); | |
1012 vncContainer.add(outerPanel); | |
1013 Panel textPanel = new Panel(new FlowLayout(FlowLayout.CENTER)); | |
1014 textPanel.add(errLabel); | |
1015 gridPanel.add(textPanel); | |
1016 gridPanel.add(new ReloginPanel(this)); | |
1017 | |
1018 } else { | |
1019 | |
1020 vncContainer.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 30)); | |
1021 vncContainer.add(errLabel); | |
1022 | |
1023 } | |
1024 | |
1025 if (inSeparateFrame) { | |
1026 vncFrame.pack(); | |
1027 } else { | |
1028 validate(); | |
1029 } | |
1030 } | |
1031 | |
1032 // | |
1033 // Stop the applet. | |
1034 // Main applet thread will terminate on first exception | |
1035 // after seeing that rfbThread has been set to null. | |
1036 // | |
1037 | |
1038 public void stop() { | |
1039 System.out.println("Stopping applet"); | |
1040 rfbThread = null; | |
1041 } | |
1042 | |
1043 // | |
1044 // This method is called before the applet is destroyed. | |
1045 // | |
1046 | |
1047 public void destroy() { | |
1048 System.out.println("Destroying applet"); | |
1049 | |
1050 vncContainer.removeAll(); | |
1051 options.dispose(); | |
1052 clipboard.dispose(); | |
1053 if (rec != null) | |
1054 rec.dispose(); | |
1055 if (rfb != null && !rfb.closed()) | |
1056 rfb.close(); | |
1057 if (inSeparateFrame) | |
1058 vncFrame.dispose(); | |
1059 } | |
1060 | |
1061 // | |
1062 // Start/stop receiving mouse events. | |
1063 // | |
1064 | |
1065 public void enableInput(boolean enable) { | |
1066 vc.enableInput(enable); | |
1067 } | |
1068 | |
1069 // | |
1070 // Close application properly on window close event. | |
1071 // | |
1072 | |
1073 public void windowClosing(WindowEvent evt) { | |
1074 System.out.println("Closing window"); | |
1075 if (rfb != null) | |
1076 disconnect(); | |
1077 | |
1078 vncContainer.hide(); | |
1079 | |
1080 if (!inAnApplet) { | |
1081 System.exit(0); | |
1082 } | |
1083 } | |
1084 | |
1085 // | |
1086 // Ignore window events we're not interested in. | |
1087 // | |
1088 | |
1089 public void windowActivated(WindowEvent evt) { | |
1090 } | |
1091 | |
1092 public void windowDeactivated(WindowEvent evt) { | |
1093 } | |
1094 | |
1095 public void windowOpened(WindowEvent evt) { | |
1096 } | |
1097 | |
1098 public void windowClosed(WindowEvent evt) { | |
1099 } | |
1100 | |
1101 public void windowIconified(WindowEvent evt) { | |
1102 } | |
1103 | |
1104 public void windowDeiconified(WindowEvent evt) { | |
1105 } | |
72 | 1106 |
73 | 1107 void getParentname(EchoClient value, int echoPort) { |
72 | 1108 if (value == null) { |
1109 | |
1110 if (clientSocket == null) { | |
1111 String pHost; | |
1112 if (mainArgs.length > 0) | |
1113 pHost = mainArgs[0]; | |
1114 else | |
1115 pHost = "cls080.ie.u-ryukyu.ac.jp"; | |
73 | 1116 // echo = new EchoClient(pHost, this); |
1117 echo = new EchoClient(pHost, this, echoPort); | |
72 | 1118 echo.openport(); |
1119 | |
1120 value = echo.hostn("1"); | |
1121 } else { | |
1122 echo = new EchoClient(); | |
1123 value = echo.Interruption(clientSocket); | |
1124 } | |
1125 } | |
1126 // proxyからの返信で接続先を決定する | |
1127 host = value.responseLine; | |
1128 parent = value.parent; | |
1129 if (value.treenum != null) { | |
1130 treenum = value.treenum; | |
1131 } else { | |
1132 treenum = echo.treenum; | |
1133 } | |
1134 if (value.leaderflag != null) { | |
1135 leaderflag = value.leaderflag; | |
1136 } else { | |
1137 leaderflag = echo.leaderflag; | |
1138 } | |
1139 System.out.println("Parent =" + parent); | |
1140 System.out.println("mynumber =" + treenum); | |
1141 System.out.println("connect host =" + host); | |
1142 System.out.println("leaderflag(boolean) = " + leaderflag); | |
1143 | |
1144 echo = value; | |
1145 | |
1146 if (host == null) { | |
1147 host = getCodeBase().getHost(); | |
1148 if (host.equals("")) { | |
1149 fatalError("HOST parameter not specified"); | |
1150 } | |
1151 } | |
73 | 1152 // port = 5999; |
72 | 1153 |
73 | 1154 } |
32 | 1155 |
73 | 1156 int castByteInt(byte[] b) { |
1157 ByteBuffer bb = ByteBuffer.wrap(b); | |
1158 int value = bb.getInt(); | |
1159 return value; | |
1160 } | |
1161 | |
1162 | |
1163 | |
30 | 1164 public static void main(Socket _clientSocket) { |
1165 MyVncClient v = new MyVncClient(); | |
60 | 1166 // v.clientSocket = _clientSocket; |
32 | 1167 // v.mainArgs = argv; |
30 | 1168 v.inAnApplet = false; |
1169 v.inSeparateFrame = true; | |
1170 | |
72 | 1171 v.echovalue = null; |
1172 | |
30 | 1173 v.init(null); |
34 | 1174 v.start_threads(); |
30 | 1175 v.start(); |
1176 } | |
32 | 1177 |
50
c07bec8c8617
change echoClient.java EchoClient.java
Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
parents:
49
diff
changeset
|
1178 public static void main(EchoClient value) { |
30 | 1179 MyVncClient v = new MyVncClient(); |
1180 v.inAnApplet = false; | |
1181 v.inSeparateFrame = true; | |
1182 | |
72 | 1183 v.echovalue = value; |
1184 | |
30 | 1185 v.init(value); |
60 | 1186 v.start_threads(); |
30 | 1187 v.start(); |
32 | 1188 |
30 | 1189 } |
60 | 1190 |
1191 public void setClientSocket(Socket sock) { | |
1192 clientSocket = sock; | |
1193 } | |
71 | 1194 public void close() { |
1195 rfb.close(); | |
1196 vncFrame.setVisible(false); | |
1197 vncFrame.dispose(); | |
1198 } | |
60 | 1199 |
1200 | |
20 | 1201 } |