diff -r 60ebcc705421 -r cf71bff5f533 test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/SocketTransport.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdwp/SocketTransport.java Wed May 30 20:54:45 2018 -0700 @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package nsk.share.jdwp; + +import nsk.share.*; + +import java.io.*; +import java.net.*; + +/** + * This class represents a socket transport for JDWP. + */ +public class SocketTransport extends Transport { + + /** + * Socket for established JDWP connection. + */ + private Socket socket = null; + + /** + * ServerSocket for listening JDWP connection. + */ + private ServerSocket serverSocket = null; + + /** + * Input stream of socket. + */ + private InputStream in = null; + + /** + * Output stream of socket. + */ + private OutputStream out = null; + + /** + * Port to listen to. + */ + int listenPort = 0; + + /** + * Make SocketTransport object with providing specified Log. + */ + public SocketTransport(Log log) { + super(log); + } + + /** + * Bind for connection from target VM to specified port number. + * If given port number is 0 then bind to any free port number. + * + * @return port number which this transport is listening for + */ + public int bind(int port) + throws IOException { + serverSocket = new ServerSocket(); + if (port == 0) { + // Only need SO_REUSEADDR if we're using a fixed port. If we + // start seeing EADDRINUSE due to collisions in free ports + // then we should retry the bind() a few times. + display("port == 0, disabling SO_REUSEADDR"); + serverSocket.setReuseAddress(false); + } + serverSocket.bind(new InetSocketAddress(port)); + listenPort = serverSocket.getLocalPort(); + return listenPort; + } + + /** + * Attach to the target VM for specified host name and port number. + */ + public void attach(String ServerName, int PortNumber) + throws UnknownHostException, IOException { + for (int i = 0; i < Binder.CONNECT_TRIES; i++ ) { + try { + socket = new Socket(ServerName, PortNumber); + display("JDWP socket connection established"); +// socket.setTcpNoDelay(true); + in = socket.getInputStream(); + out = socket.getOutputStream(); + return; + } catch (IOException e) { + display("Attempt #" + i + " to establish JDWP socket connection failed:\n\t" + e); + try { + Thread.currentThread().sleep(Binder.CONNECT_TRY_DELAY); + } catch (InterruptedException ie) { + ie.printStackTrace(log.getOutStream()); + throw new Failure("Thread interrupted while establishing JDWP connection: \n\t" + + ie); + } + } + } + throw new IOException("Timeout exceeded while establishing JDWP socket connection to " + + ServerName + ":" + PortNumber); + } + + /** + * Accept connection from target VM for already boud port. + */ + public void accept() + throws IOException { + + if (serverSocket == null) + throw new Failure("Attempt to accept JDWP socket connection from unbound port"); + + socket = serverSocket.accept(); + serverSocket.close(); + serverSocket = null; + + in = socket.getInputStream(); + out = socket.getOutputStream(); + } + + /** + * Close socket and streams. + */ + public void close() throws IOException { + + if (socket == null) + return; + + if (out != null) { + flush(); + out.close(); + } + + if (in != null) { + in.close(); + } + + if (socket != null) { + socket.close(); + socket = null; + } + + if (serverSocket != null) { + serverSocket.close(); + serverSocket = null; + } + } + + /** + * Return number of bytes that can be read. + */ + public int available() throws IOException { + return in.available(); + }; + + /** + * Flush bytes being buffered for writing if any. + */ + public void flush() throws IOException { + out.flush(); + } + + /** + * Set timeout for reading data in milliseconds. + */ + public void setReadTimeout(long millisecs) throws IOException { + socket.setSoTimeout((int)millisecs); + } + + /** + * Read the next byte of data from the socket. + * The value byte is returned as an int in the range 0 to 255. + * If no byte is available, the value -1 is returned. + */ + public byte read() throws IOException { + int b = in.read(); + if (b < 0) { + throw new IOException("JDWP socket connection closed by remote host"); + } + return (byte) b; + }; + + /** + * Write the specified byte to the socket. + */ + public void write(int b) throws IOException { + out.write(b); + }; +}