1 13 package org.eclipse.jdi.internal.connect; 14 15 import java.io.DataInputStream ; 16 import java.io.EOFException ; 17 import java.io.IOException ; 18 import java.io.InputStream ; 19 import java.io.OutputStream ; 20 import java.net.ServerSocket ; 21 import java.net.Socket ; 22 import java.net.SocketTimeoutException ; 23 import java.util.Arrays ; 24 25 import org.eclipse.jdi.TimeoutException; 26 27 import com.sun.jdi.connect.TransportTimeoutException; 28 import com.sun.jdi.connect.spi.ClosedConnectionException; 29 import com.sun.jdi.connect.spi.Connection; 30 import com.sun.jdi.connect.spi.TransportService; 31 32 public class SocketTransportService extends TransportService { 33 34 private static final byte[] handshakeBytes = "JDWP-Handshake".getBytes(); 36 private Capabilities fCapabilities = new Capabilities() { 37 public boolean supportsAcceptTimeout() { 38 return true; 39 } 40 41 public boolean supportsAttachTimeout() { 42 return true; 43 } 44 45 public boolean supportsHandshakeTimeout() { 46 return true; 47 } 48 49 public boolean supportsMultipleConnections() { 50 return false; 51 } 52 }; 53 54 private class SocketListenKey extends ListenKey { 55 private String fAddress; 56 57 SocketListenKey(String address) { 58 fAddress = address; 59 } 60 61 66 public String address() { 67 return fAddress; 68 } 69 } 70 71 private Socket fSocket; 73 74 private InputStream fInput; 75 76 private OutputStream fOutput; 77 78 private ServerSocket fServerSocket; 80 81 87 public Connection accept(ListenKey listenKey, long attachTimeout, long handshakeTimeout) throws IOException { 88 if (attachTimeout > 0){ 89 if (attachTimeout > Integer.MAX_VALUE) { 90 attachTimeout = Integer.MAX_VALUE; } 92 fServerSocket.setSoTimeout((int) attachTimeout); 93 } 94 try { 95 fSocket = fServerSocket.accept(); 96 } catch (SocketTimeoutException e) { 97 throw new TransportTimeoutException(); 98 } 99 fInput = fSocket.getInputStream(); 100 fOutput = fSocket.getOutputStream(); 101 performHandshake(fInput, fOutput, handshakeTimeout); 102 return new SocketConnection(this); 103 } 104 105 111 public Connection attach(String address, long attachTimeout, long handshakeTimeout) throws IOException { 112 String [] strings = address.split(":"); String host = "localhost"; int port = 0; 115 if (strings.length == 2) { 116 host = strings[0]; 117 port = Integer.parseInt(strings[1]); 118 } else { 119 port = Integer.parseInt(strings[0]); 120 } 121 122 return attach(host, port, attachTimeout, handshakeTimeout); 123 } 124 125 public Connection attach(final String host, final int port, long attachTimeout, final long handshakeTimeout) throws IOException { 126 if (attachTimeout > 0){ 127 if (attachTimeout > Integer.MAX_VALUE) { 128 attachTimeout = Integer.MAX_VALUE; } 130 } 131 132 final IOException [] ex = new IOException [1]; 133 Thread attachThread = new Thread (new Runnable () { 134 public void run() { 135 try { 136 fSocket = new Socket (host, port); 137 fInput = fSocket.getInputStream(); 138 fOutput = fSocket.getOutputStream(); 139 performHandshake(fInput, fOutput, handshakeTimeout); 140 } catch (IOException e) { 141 ex[0] = e; 142 } 143 } 144 }, ConnectMessages.SocketTransportService_0); 145 attachThread.setDaemon(true); 146 attachThread.start(); 147 try { 148 attachThread.join(attachTimeout); 149 if (attachThread.isAlive()) { 150 attachThread.interrupt(); 151 throw new TimeoutException (); 152 } 153 } catch (InterruptedException e) { 154 } 155 156 if (ex[0] != null) { 157 throw ex[0]; 158 } 159 160 161 return new SocketConnection(this); 162 } 163 164 void performHandshake(final InputStream in, final OutputStream out, final long timeout) throws IOException { 165 final IOException [] ex = new IOException [1]; 166 final boolean[] handshakeCompleted = new boolean[1]; 167 168 Thread t = new Thread (new Runnable () { 169 public void run() { 170 try { 171 writeHandshake(out); 172 readHandshake(in); 173 handshakeCompleted[0] = true; 174 } catch (IOException e) { 175 ex[0] = e; 176 } 177 } 178 }, ConnectMessages.SocketTransportService_1); 179 t.setDaemon(true); 180 t.start(); 181 try { 182 t.join(timeout); 183 } catch (InterruptedException e1) { 184 } 185 186 if (handshakeCompleted[0]) 187 return; 188 189 try { 190 in.close(); 191 out.close(); 192 } catch (IOException e) { 193 } 194 195 if (ex[0] != null) 196 throw ex[0]; 197 198 throw new TransportTimeoutException(); 199 } 200 201 private void readHandshake(InputStream input) throws IOException { 202 try { 203 DataInputStream in = new DataInputStream (input); 204 byte[] handshakeInput = new byte[handshakeBytes.length]; 205 in.readFully(handshakeInput); 206 if (!Arrays.equals(handshakeInput, handshakeBytes)) 207 throw new IOException ("Received invalid handshake"); } catch (EOFException e) { 209 throw new ClosedConnectionException(); 210 } 211 } 212 213 private void writeHandshake(OutputStream out) throws IOException { 214 out.write(handshakeBytes); 215 } 216 217 222 public Capabilities capabilities() { 223 return fCapabilities; 224 } 225 226 231 public String description() { 232 return "org.eclipse.jdt.debug: Socket Implementation of TransportService"; } 234 235 240 public String name() { 241 return "org.eclipse.jdt.debug_SocketTransportService"; } 243 244 249 public ListenKey startListening() throws IOException { 250 return startListening(null); 252 } 253 254 259 public ListenKey startListening(String address) throws IOException { 260 String host = null; 261 int port = 0; if (address != null) { 264 String [] strings = address.split(":"); host = "localhost"; if (strings.length == 2) { 267 host = strings[0]; 268 port = Integer.parseInt(strings[1]); 269 } else { 270 port = Integer.parseInt(strings[0]); 271 } 272 } 273 if (host == null) { 274 host = "localhost"; } 276 277 fServerSocket = new ServerSocket (port); 278 port = fServerSocket.getLocalPort(); 279 ListenKey listenKey = new SocketListenKey(host + ":" + port); return listenKey; 281 } 282 283 288 public void stopListening(ListenKey arg1) throws IOException { 289 if (fServerSocket != null) { 290 try { 291 fServerSocket.close(); 292 } catch (IOException e) { 293 } 294 } 295 fServerSocket = null; 296 } 297 298 public void close() { 299 if (fSocket != null) { 300 try { 301 fSocket.close(); 302 } catch (IOException e) { 303 } 304 } 305 306 fServerSocket = null; 307 fSocket = null; 308 fInput = null; 309 fOutput = null; 310 } 311 312 315 public InputStream getInputStream() { 316 return fInput; 317 } 318 319 322 public OutputStream getOutputStream() { 323 return fOutput; 324 } 325 } 326 | Popular Tags |