⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rfbproto.java

📁 teamviewer source code vc++
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
//
//  Copyright (C) 2001,2002 HorizonLive.com, Inc.  All Rights Reserved.
//  Copyright (C) 2001,2002 Constantin Kaplinsky.  All Rights Reserved.
//  Copyright (C) 2000 Tridia Corporation.  All Rights Reserved.
//  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
//  Copyright (C) 2003 Helmut Eller <helmut@online-marketwatch.com>
//
//  This is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  This software is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this software; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
//  USA.
//

//
// RfbProto.java
//

import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.util.zip.*;

class TunnelReader extends InputStream {
    URL url;
    InputStream tunnel;

    TunnelReader (URL url) throws IOException {
	this.url = url;
	this.tunnel = connect (url);
    }
    
    InputStream getInputStream () throws IOException {
	return this;
	// return connect (url);
    }

    private final static void trace (String string) {
	// System.err.println ("Reader: " + string);
    }
    
    InputStream connect (URL url) throws IOException {
	trace ("connect");
	URLConnection get = url.openConnection();
	get.setDoOutput (false);
	get.setDoInput (true);
	get.setUseCaches (false);	
	get.setRequestProperty("X-Agent","DynGate");
	get.connect ();
	return get.getInputStream ();
    }

    void reconnect () throws IOException {
	tunnel = connect (url);
    }

    synchronized public int read () throws IOException {
	trace ("read");
	for (;;) {
	    int n = tunnel.read ();
	    if (n >= 0) {
		// trace ("read: " + " -> " + n);
		return n;
	    } else 
		reconnect ();
	}
    }
    
    synchronized public int read (byte[] bytes) throws IOException  {
	trace ("read");
	for (;;) {
	    int n = tunnel.read (bytes);
	    if (n >= 0) {
		// trace ("read: " + " -> " + n);
		return n;
	    } else 
		reconnect ();
	}
    }

    synchronized public int read (byte[] bytes, int offset, int length) 
	throws IOException {
	trace ("read");
	for (;;) {
	    int n = tunnel.read (bytes, offset, length);
	    if (n >= 0) {
		// trace ("read: " + " -> " + n);
		return n;
	    } else 
		reconnect ();
	}
    }

    public long skip (long n) throws IOException {
	trace ("skip ...");
	return tunnel.skip (n);
    }

    synchronized public int available () throws IOException {
	trace ("available");
	int n = tunnel.available ();
	// trace ("available: -> " + n);
	return n;
    }
    
    public void close () throws IOException {
	trace ("Reader close ...");
	tunnel.close ();
	tunnel = null;
	url = null;
    }
    
    public void mark (int readlimit) {
	trace ("Reader mark ...");
	tunnel.mark (readlimit);
    }
    
    public void reset () throws IOException {
	trace ("Reader reset ...");
	tunnel.reset ();
    }

    public boolean markSupported () {
	trace ("markSupported ...");
	return tunnel.markSupported ();
    }
}

class TunnelWriter extends OutputStream {
    URL url;
    URLConnection post;
    OutputStream out;

    TunnelWriter (URL url) throws IOException {
	this.url = url;
	// connect ();
    }

    OutputStream getOutputStream () {
	return this;
    }

    private final static void trace (String string) {
	// System.err.println ("Writer: " + string);
    }
    
    void connect () throws IOException {
	trace ("connect");
	URLConnection post = url.openConnection();
	post.setDoOutput (true);
	post.setDoInput (true);
	post.setUseCaches (false);
	post.setRequestProperty("X-Agent","DynGate");
	out = post.getOutputStream ();
	this.post = post;
    }

    void forceOutput () throws IOException {
	trace ("flush");
	out.flush ();
	out.close ();
	InputStream in = post.getInputStream ();
	// Commented code is for crappy Netscape4.
	try { 
	    int b = in.read ();  // needed for Explorer
	    // trace ("read -> 1 [" + b + "]");
	    // in.close ();
	} catch (Exception e) {
	    // e.printStackTrace ();
	    // System.err.println (e.getMessage ());
	}
    }
    
    synchronized public void flush () throws IOException {
	forceOutput ();
    }

    synchronized public void write (int b) throws IOException  {
	trace ("write");
	connect ();
	out.write (b);
	forceOutput ();
	// trace ("write <- 1");
    }

    synchronized public void write (byte[] b) throws IOException {
	trace ("write");
	connect ();
	out.write (b);
	forceOutput ();
	// trace ("write <- " + b.length);
    }

    synchronized public void write (byte[] b, int offset, int length) 
	throws IOException {
	trace ("write");
	connect ();
	out.write (b, offset, length);
	forceOutput ();
	// trace ("write <- " + length);
    }
    
    public void close () throws IOException {
	trace ("close");
	flush ();
	post = null;
	out = null;
    }
}

class RfbProto {

  final String versionMsg = "RFB 003.003\n";
  final static int ConnFailed = 0, NoAuth = 1, VncAuth = 2;
  final static int VncAuthOK = 0, VncAuthFailed = 1, VncAuthTooMany = 2;

  final static int FramebufferUpdate = 0, SetColourMapEntries = 1, Bell = 2,
    ServerCutText = 3;

  final int SetPixelFormat = 0, FixColourMapEntries = 1, SetEncodings = 2,
    FramebufferUpdateRequest = 3, KeyboardEvent = 4, PointerEvent = 5,
    ClientCutText = 6;

  final static int
    EncodingRaw            = 0,
    EncodingCopyRect       = 1,
    EncodingRRE            = 2,
    EncodingCoRRE          = 4,
    EncodingHextile        = 5,
    EncodingZlib           = 6,
    EncodingTight          = 7,
    EncodingCompressLevel0 = 0xFFFFFF00,
    EncodingQualityLevel0  = 0xFFFFFFE0,
    EncodingXCursor        = 0xFFFFFF10,
    EncodingRichCursor     = 0xFFFFFF11,
    EncodingLastRect       = 0xFFFFFF20,
    EncodingNewFBSize      = 0xFFFFFF21;

  final int HextileRaw			= (1 << 0);
  final int HextileBackgroundSpecified	= (1 << 1);
  final int HextileForegroundSpecified	= (1 << 2);
  final int HextileAnySubrects		= (1 << 3);
  final int HextileSubrectsColoured	= (1 << 4);

  final static int TightExplicitFilter  = 0x04;
  final static int TightFill            = 0x08;
  final static int TightJpeg            = 0x09;
  final static int TightMaxSubencoding  = 0x09;
  final static int TightFilterCopy      = 0x00;
  final static int TightFilterPalette   = 0x01;
  final static int TightFilterGradient  = 0x02;

  final static int TightMinToCompress   = 12;

  String host;
  int port;
  Socket sock;
  DataInputStream is;
  OutputStream os;
  SessionRecorder rec;
  boolean inNormalProtocol = false;
  VncViewer viewer;

  // Java on UNIX does not call keyPressed() on some keys, for example
  // swedish keys To prevent our workaround to produce duplicate
  // keypresses on JVMs that actually works, keep track of if
  // keyPressed() for a "broken" key was called or not. 
  boolean brokenKeyPressed = false;

  // This will be set to true on the first framebuffer update
  // containing Zlib- or Tight-encoded data.
  boolean wereZlibUpdates = false;

  // This will be set to false if the startSession() was called after
  // we have received at least one Zlib- or Tight-encoded framebuffer
  // update.
  boolean recordFromBeginning = true;

  // This fields are needed to show warnings about inefficiently saved
  // sessions only once per each saved session file.
  boolean zlibWarningShown;
  boolean tightWarningShown;

  // Before starting to record each saved session, we set this field
  // to 0, and increment on each framebuffer update. We don't flush
  // the SessionRecorder data into the file before the second update. 
  // This allows us to write initial framebuffer update with zero
  // timestamp, to let the player show initial desktop before
  // playback.
  int numUpdatesInSession;

    int makeSessionIDRequest (URL url) throws IOException {
	URLConnection c = url.openConnection();
	System.err.println ("UrlConnection.class: " 
			    + c.getClass ());
	c.setDoInput (true);
	c.setUseCaches (false);
	c.connect ();
	InputStream in = c.getInputStream ();
	byte[] headdata = new byte[2];
	int count = in.read (headdata);

	byte[] buffer = new byte[8];	
	count = in.read (buffer);
	System.err.println ("buffer: <<" 
			    + new String (buffer) + ">>");
	if (count != 8)
	    throw new IOException ("Couldn't read session id.");
	int id = (buffer[0] - 48) * 10000000
			+ (buffer[1] - 48) * 1000000
			+ (buffer[2] - 48) * 100000
			+ (buffer[3] - 48) * 10000
			+ (buffer[4] - 48) * 1000
			+ (buffer[5] - 48) * 100
			+ (buffer[6] - 48) * 10
			+ (buffer[7] - 48);
	System.err.println ("session-id: " + id);
	return id;
    }

    int getSessionID (URL url) throws IOException {
	final int OPEN_STATE_PENDING = 1;
	final int OPEN_STATE_OK = 2;
	final int OPEN_STATE_FAILED = 3;
	class Opener extends Thread  {
	    URL url;
	    int id;
	    IOException error;
	    int openState = OPEN_STATE_PENDING;
	    Opener (URL u) { url = u ;}
	    public void run () {
		synchronized (this) {
		    try {
			id = makeSessionIDRequest (url);
			openState = OPEN_STATE_OK;
		    } catch (IOException e) {
			error = e;
			openState = OPEN_STATE_FAILED;
		    }
		    this.notifyAll ();
		}
	    }
	}
	Opener o = new Opener (url);
	o.start ();
	synchronized (o) {
	    long end = System.currentTimeMillis () + (15 * 1000);
	    do {
		try { o.wait (end - System.currentTimeMillis ()); } 
		catch (InterruptedException e) {}
	    } while (o.openState == OPEN_STATE_PENDING
		     && ((end - System.currentTimeMillis ()) > 0));
	    switch (o.openState)  {
	    case OPEN_STATE_PENDING: throw new IOException ("timeout");
	    case OPEN_STATE_FAILED: throw o.error;
	    case OPEN_STATE_OK: return o.id;
	    default: throw new Error ("Bug");
	    }
	}
    }
	
    void initHttp (String host, int port, int DynGateID) 
	throws IOException {
		int sid = 0;
		try
		{
			sid = getSessionID (new URL ("http", host, port,"/din.aspx?s=00000000&client=DynGate"));		
		} catch (IOException e) {
			System.err.println ("Tunnel-connection failed: "
					+ e.getMessage () + "\n");
			throw e;
		}
		URL wurl = new URL("http", host, port, "/dout.aspx?s=" + sid + "&client=DynGate");
		URL rurl = new URL("http", host, port, "/din.aspx?s=" + sid + "&client=DynGate");
	
		os = new TunnelWriter (wurl).getOutputStream();
		//Send our connection-request
		byte[] auth = new byte[9];
		auth[0] = 23;
		auth[1] = 36;
		auth[2] = 26;
		auth[3] = 4;
		auth[4] = 0;
		auth[5] = (byte)(DynGateID);
		auth[6] = (byte)(DynGateID >> 8);
		auth[7] = (byte)(DynGateID >> 16);
		auth[8] = (byte)(DynGateID >> 24);
		os.write(auth);
		os.flush();

		is = new DataInputStream 
			(new BufferedInputStream 
			(new TunnelReader (rurl).getInputStream (),
			 16384));
    }

    void initTcp (String host, int port) throws IOException {
	sock = new Socket (host, port);
	is = new DataInputStream 
	    (new BufferedInputStream (sock.getInputStream (),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -