import java.awt.Rectangle; import java.awt.Robot; import java.awt.Toolkit; import java.awt.event.InputEvent; import java.awt.image.BufferedImage; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.URLDecoder; import java.util.Date; import javax.imageio.ImageIO; public class RemoteDesktop { enum HttpStatus { OK(200, "OK"), BAD_REQUEST(400, "Bad request"), NOT_FOUND(404, "Not found"); final int code; final String message; private HttpStatus(int code, String message) { this.code = code; this.message = message; } } private static final int SERVER_PORT = 6060; private static final int CLICK_REFRESH_DELAY_MS = 2000; private static final Rectangle SCREEN_RECT = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()); private static final String IMAGE_CODEC = "jpeg"; private static String HOST_NAME; private ServerSocket serverSocket; private Robot robot; public RemoteDesktop() throws Exception { serverSocket = new ServerSocket(SERVER_PORT); robot = new Robot(); } public void run() { for (;;) { try { Socket socket = serverSocket.accept(); socket.setSoTimeout(10000); serve(socket); } catch (IOException e) { e.printStackTrace(); return; } } } private void serve(Socket socket) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream()); String request = in.readLine(); logOutput("REQ: " + request); String path = parseRequestLocation(request); if (path == null || path.length() < 1) { sendText(out, HttpStatus.BAD_REQUEST, "Bad Request: " + request); } else { if (path.startsWith("/screen.map?")) { int q = path.indexOf('?'); int comma = path.indexOf(',', q); int x = Integer.parseInt(path.substring(q + 1, comma)); int y = Integer.parseInt(path.substring(comma + 1)); clickMouse(x, y); sleep(CLICK_REFRESH_DELAY_MS); sendMainPage(out); } else if (path.equals("/screen")) { sendScreenshot(out); } else if (path.equals("/")) { sendMainPage(out); } else { sendText(out, HttpStatus.NOT_FOUND, "Page not found"); } } out.flush(); out.close(); } private static void sleep(long millis) { try { Thread.sleep(millis); } catch (InterruptedException e) { } } private String parseRequestLocation(String request) throws UnsupportedEncodingException { if (request != null) { String tokens[] = request.split("\\s+"); if ((tokens.length == 3) && tokens[0].equals("GET") && (tokens[2].equals("HTTP/1.0") || tokens[2].equals("HTTP/1.1"))) { return URLDecoder.decode(tokens[1], "UTF-8"); } } return null; } private void clickMouse(int x, int y) { logOutput("CLICK! [" + x + "," + y + "]"); robot.mouseMove(x, y); robot.mousePress(InputEvent.BUTTON1_MASK); robot.mouseRelease(InputEvent.BUTTON1_MASK); } private void sendScreenshot(BufferedOutputStream out) throws IOException { BufferedImage im = robot.createScreenCapture(SCREEN_RECT); ByteArrayOutputStream output = new ByteArrayOutputStream(500000); ImageIO.write(im, IMAGE_CODEC, output); sendContent(out, HttpStatus.OK, "image/" + IMAGE_CODEC, output.toByteArray()); } private void sendMainPage(BufferedOutputStream out) throws IOException { String output = "" + HOST_NAME + " Desktop"; sendText(out, HttpStatus.OK, output); } private static void sendContent(BufferedOutputStream out, HttpStatus status, String contentType, byte content[]) throws IOException { Date date = new Date(); int contentLength = content.length; String headers = "HTTP/1.0 " + status.code + " " + status.message + "\r\n" + "Date: " + date + "\r\n" + "Content-Type: " + contentType + "\r\n" + "Pragma: no-cache\r\n" + ((contentLength > 0) ? "Content-Length: " + contentLength + "\r\n" : "") + "Last-Modified: " + date + "\r\n" + "\r\n"; out.write(headers.getBytes()); out.write(content); } private static void sendText(BufferedOutputStream out, HttpStatus status, String message) throws IOException { sendContent(out, status, "text/html", message.getBytes()); } private static void logOutput(String string) { System.out.println(new Date() + " WEB: " + string); } public static void main(String[] args) throws Exception { HOST_NAME = InetAddress.getLocalHost().getHostName(); (new RemoteDesktop()).run(); } }