/** Attach to the specified address with optional attach and handshake timeout. */ public Connection attach(String address, long attachTimeout, long handshakeTimeout) throws IOException { if (address == null) { throw new NullPointerException("address is null"); } if (attachTimeout < 0 || handshakeTimeout < 0) { throw new IllegalArgumentException("timeout is negative"); } int splitIndex = address.indexOf(':'); String host; String portStr; if (splitIndex < 0) { host = InetAddress.getLocalHost().getHostName(); portStr = address; } else { host = address.substring(0, splitIndex); portStr = address.substring(splitIndex + 1); } int port; try { port = Integer.decode(portStr).intValue(); } catch (NumberFormatException e) { throw new IllegalArgumentException("unable to parse port number in address"); } // open TCP connection to VM InetSocketAddress sa = new InetSocketAddress(host, port); Socket s = new Socket(); try { s.connect(sa, (int) attachTimeout); } catch (SocketTimeoutException exc) { try { s.close(); } catch (IOException x) { } throw new TransportTimeoutException("timed out trying to establish connection"); } // handshake with the target VM try { handshake(s, handshakeTimeout); } catch (IOException exc) { try { s.close(); } catch (IOException x) { } throw exc; } return new SocketConnection(s); }
/** Handshake with the debuggee */ void handshake(Socket s, long timeout) throws IOException { s.setSoTimeout((int) timeout); byte[] hello = "JDWP-Handshake".getBytes("UTF-8"); s.getOutputStream().write(hello); byte[] b = new byte[hello.length]; int received = 0; while (received < hello.length) { int n; try { n = s.getInputStream().read(b, received, hello.length - received); } catch (SocketTimeoutException x) { throw new IOException("handshake timeout"); } if (n < 0) { s.close(); throw new IOException("handshake failed - connection prematurally closed"); } received += n; } for (int i = 0; i < hello.length; i++) { if (b[i] != hello[i]) { throw new IOException("handshake failed - unrecognized message from target VM"); } } // disable read timeout s.setSoTimeout(0); }
public void close() throws IOException { synchronized (closeLock) { if (closed) { return; } socketOutput.close(); socketInput.close(); socket.close(); closed = true; } }