view src/myVncProxy/MyRfbProto.java @ 40:dd1321b67f95

sendReadData : newSingleThreadExecutor()
author e085711
date Mon, 06 Jun 2011 12:26:12 +0900
parents f399eec66846
children 08317224ce21
line wrap: on
line source

package myVncProxy;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList;

import javax.imageio.ImageIO;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.io.OutputStream;

class MyRfbProto extends RfbProto {

	private int messageType;
	private int rectangles;
	private int rectX;
	private int rectY;
	private int rectW;
	private int rectH;
	private int encoding;
	private int zLen;
	private int dataLen; 

	private ServerSocket servSock;
	private int acceptPort;
	private byte initData[];
	private LinkedList <Socket> cliListTmp;
	private LinkedList <Socket> cliList;
	private LinkedList <Thread> sendThreads;
	boolean createBimgFlag;
	
	ExecutorService executor;
	
	
	byte[] pngBytes;
	
	MyRfbProto(String h, int p, VncViewer v ) throws IOException {
		super(h, p, v);
		cliList = new LinkedList <Socket>();
		cliListTmp = new LinkedList <Socket>();
		createBimgFlag = false;
		sendThreads = new LinkedList <Thread>();
//		executor = Executors.newCachedThreadPool();
		executor = Executors.newSingleThreadExecutor();
	}

	MyRfbProto(String h, int p) throws IOException {
		super(h, p);
		cliList = new LinkedList <Socket>();
		cliListTmp = new LinkedList <Socket>();
		createBimgFlag = false;
		sendThreads = new LinkedList <Thread>();
//		executor = Executors.newCachedThreadPool();
		executor = Executors.newSingleThreadExecutor();
	}

	void initServSock(int port) throws IOException{
		servSock = new ServerSocket(port);
		acceptPort = port;
	}
	void selectPort(){
		int i = 5550;
		while(true){
			try{
				initServSock(i);
				break;
			}catch(BindException e){
				i++;
				continue;
			}catch(IOException e){

			}
		}
		System.out.println("accept port = "+i);
	}
	int getAcceptPort(){
		return acceptPort;
	}
	void setSoTimeout(int num) throws IOException {
		servSock.setSoTimeout(num);
	}
	
	Socket accept() throws IOException {
		return servSock.accept();
	}

	void addSock(Socket sock){
		cliList.add(sock);
	}
	void addSockTmp(Socket sock){
		System.out.println("connected "+sock.getInetAddress());
		cliListTmp.add(sock);
	}
	
	void mark(int len) throws IOException {
		is.mark(len);
	}

	void reset() throws IOException {
		is.reset();
 	}

	boolean markSupported() {
		return is.markSupported();
	}
	
	void readServerInit() throws IOException {
		
		mark(255);
		skipBytes(20);
		int nlen = readU32();
		int blen = 20+4+nlen;
		initData = new byte[blen];
		reset();

		mark(blen);
		readFully(initData);
		reset();
		
		framebufferWidth = readU16();
		framebufferHeight = readU16();
		bitsPerPixel = readU8();
		depth = readU8();
		bigEndian = (readU8() != 0);
		trueColour = (readU8() != 0);
		redMax = readU16();
		greenMax = readU16();
		blueMax = readU16();
		redShift = readU8();
		greenShift = readU8();
		blueShift = readU8();
		byte[] pad = new byte[3];
		readFully(pad);
		int nameLength = readU32();
		byte[] name = new byte[nameLength];
		readFully(name);
		desktopName = new String(name);

		// Read interaction capabilities (TightVNC protocol extensions)
		if (protocolTightVNC) {
			int nServerMessageTypes = readU16();
			int nClientMessageTypes = readU16();
			int nEncodingTypes = readU16();
			readU16();
			readCapabilityList(serverMsgCaps, nServerMessageTypes);
			readCapabilityList(clientMsgCaps, nClientMessageTypes);
			readCapabilityList(encodingCaps, nEncodingTypes);
		}

		inNormalProtocol = true;
	}

	void sendInitData(Socket sock) throws IOException{
			sock.getOutputStream().write(initData);
	}

	void sendData(byte b[]){
		try{
			for(Socket cli : cliList){
				try{
					cli.getOutputStream().write(b, 0, b.length);
				}catch(IOException e){
					// if socket closed
					cliList.remove(cli);
				}
			}
//		System.out.println("cliSize="+cliSize());
		}catch(Exception e){
		}
	}
	
	void sendPngImage(){
		try{
			for(Socket cli : cliListTmp){
				try{
					sendPngData(cli);
					addSock(cli);
				}catch(IOException e){
					// if socket closed
					cliListTmp.remove(cli);
				}
			}
//		System.out.println("cliSize="+cliSize());
		}catch(Exception e){
		}
		cliListTmp.clear();
	}
	
	

	boolean ready() throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		return br.ready();
	}	

	int cliSize(){
		return cliList.size();
	}	
	void printNumBytesRead(){
		System.out.println("numBytesRead="+numBytesRead);
	}	
	void bufResetSend(int size) throws IOException {
		reset();
		int len = size;
		if(available() < size )
			len = available();
		byte buffer[] = new byte[len];
		readFully(buffer);
		sendData(buffer);
	}
	void readSendData()throws IOException{
		byte buffer[] = new byte[dataLen];
		readFully(buffer);
		reset();

		for(Socket cli : cliList){
			try{
				OutputStream out = cli.getOutputStream();
				executor.execute(new SendThread(out, buffer));
			}catch(IOException e){
				// if client socket closed
				cliListTmp.remove(cli);
			}catch(Exception e){
				
			}

		}
	}
	void regiFramebufferUpdate()throws IOException{
		mark(20);
		messageType = readU8();
		skipBytes(1);
		rectangles = readU16();
		rectX = readU16();
		rectY = readU16();
		rectW = readU16();
		rectH = readU16();
		encoding = readU32();
		if(encoding == 16)
			zLen = readU32();
		reset();
	}
	void checkAndMark() throws IOException{
		switch(encoding){
		case RfbProto.EncodingRaw:
			dataLen = rectW * rectH * 4 + 16;
			mark(dataLen);
			break;
		case RfbProto.EncodingZRLE:
			dataLen = zLen+20;
			mark(dataLen);
			break;
		default:
			mark(1000000);
			}
	}
	BufferedImage createBufferedImage(Image img){
		BufferedImage bimg = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB  );

		Graphics g = bimg.getGraphics();
		g.drawImage(img, 0, 0, null);
		g.dispose();
		return bimg;
	}

	void createPngBytes(BufferedImage bimg)throws IOException {
		pngBytes = getImageBytes(bimg , "png");
	}
	byte[] getBytes(BufferedImage img)throws IOException { 
		byte[] b = getImageBytes(img, "png");
		return b;
	}
	
	byte[] getImageBytes(BufferedImage image, String imageFormat) throws IOException {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		BufferedOutputStream os = new BufferedOutputStream(bos);
		image.flush();
		ImageIO.write(image, imageFormat, os);
		os.flush();
		os.close();
		return bos.toByteArray();
	}

	void sendPngData(Socket sock)throws IOException{
		byte[] dataLength = castIntByte(pngBytes.length);
		sock.getOutputStream().write(dataLength);
		sock.getOutputStream().write(pngBytes);
	}
	byte[] castIntByte(int len){
		byte[] b = new byte[4];
		b[0] = (byte)((len >>> 24 ) & 0xFF);
		b[1] = (byte)((len >>> 16 ) & 0xFF);
		b[2] = (byte)((len >>> 8  ) & 0xFF);
		b[3] = (byte)((len >>> 0  ) & 0xFF);
		return b;
	}
	
	BufferedImage createBimg()throws IOException{
		BufferedImage bimg = ImageIO.read(new ByteArrayInputStream(pngBytes));
		return bimg;
	}
	void readPngData()throws IOException{
		pngBytes = new byte[is.available()];
		readFully(pngBytes);
	}
	void printFramebufferUpdate(){
	
		System.out.println("messageType=" + messageType);
		System.out.println("rectangles="+rectangles);
		System.out.println("encoding=" + encoding);
		switch(encoding){
		case RfbProto.EncodingRaw:
			System.out.println("rectW * rectH * 4 + 16 =" + rectW * rectH * 4 + 16);
			break;
		default:
		}
	}
}