Path: blob/master/test/jdk/java/net/SocketImpl/SocketImplCombinations.java
41152 views
/*1* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 822049326* @modules java.base/java.net:+open java.base/sun.nio.ch:+open27* @run testng/othervm SocketImplCombinations28* @summary Test Socket and ServerSocket with combinations of SocketImpls29*/3031import java.io.FileDescriptor;32import java.io.IOException;33import java.io.InputStream;34import java.io.OutputStream;35import java.lang.reflect.Field;36import java.net.InetAddress;37import java.net.InetSocketAddress;38import java.net.Proxy;39import java.net.ServerSocket;40import java.net.Socket;41import java.net.SocketAddress;42import java.net.SocketImpl;43import java.net.SocketImplFactory;44import java.nio.channels.ServerSocketChannel;45import java.nio.channels.SocketChannel;46import java.util.function.BiConsumer;4748import org.testng.annotations.Test;49import static org.testng.Assert.*;5051@Test52public class SocketImplCombinations {5354/**55* Test creating an unconnected Socket, it should be created with a platform SocketImpl.56*/57public void testNewSocket1() throws IOException {58try (Socket s = new Socket()) {59SocketImpl si = getSocketImpl(s);60assertTrue(isSocksSocketImpl(si));61SocketImpl delegate = getDelegate(si);62assertTrue(isPlatformSocketImpl(delegate));63}64}6566/**67* Test creating a connected Socket, it should be created with a platform SocketImpl.68*/69public void testNewSocket2() throws IOException {70try (ServerSocket ss = boundServerSocket()) {71try (Socket s = new Socket(ss.getInetAddress(), ss.getLocalPort())) {72SocketImpl si = getSocketImpl(s);73assertTrue(isSocksSocketImpl(si));74SocketImpl delegate = getDelegate(si);75assertTrue(isPlatformSocketImpl(delegate));76}77}78}7980/**81* Test creating a Socket for a DIRECT connection, it should be created with a82* platform SocketImpl.83*/84public void testNewSocket3() throws IOException {85try (Socket s = new Socket(Proxy.NO_PROXY)) {86SocketImpl si = getSocketImpl(s);87assertTrue(isPlatformSocketImpl(si));88}89}9091/**92* Test creating a Socket for a SOCKS connection, it should be created with a93* SOCKS SocketImpl.94*/95public void testNewSocket4() throws IOException {96var address = new InetSocketAddress("127.0.0.1", 1080);97var socksProxy = new Proxy(Proxy.Type.SOCKS, address);98try (Socket s = new Socket(socksProxy)) {99SocketImpl si = getSocketImpl(s);100assertTrue(isSocksSocketImpl(si));101SocketImpl delegate = getDelegate(si);102assertTrue(isPlatformSocketImpl(delegate));103}104}105106/**107* Test creating a Socket for a HTTP proxy connection, it should be created with108* a HTTP proxy SocketImpl.109*/110public void testNewSocket5() throws IOException {111var address = new InetSocketAddress("127.0.0.1", 8080);112var httpProxy = new Proxy(Proxy.Type.HTTP, address);113try (Socket s = new Socket(httpProxy)) {114SocketImpl si = getSocketImpl(s);115assertTrue(isHttpConnectSocketImpl(si));116SocketImpl delegate = getDelegate(si);117assertTrue(isPlatformSocketImpl(delegate));118}119}120121/**122* Test creating a Socket no SocketImpl. A platform SocketImpl should be123* created lazily.124*/125public void testNewSocket6() throws IOException {126Socket s = new Socket((SocketImpl) null) { };127try (s) {128assertTrue(getSocketImpl(s) == null);129s.bind(loopbackSocketAddress()); // force SocketImpl to be created130SocketImpl si = getSocketImpl(s);131assertTrue(isSocksSocketImpl(si));132SocketImpl delegate = getDelegate(si);133assertTrue(isPlatformSocketImpl(delegate));134}135}136137/**138* Test creating a Socket with a custom SocketImpl.139*/140public void testNewSocket7() throws IOException {141Socket s = new Socket(new CustomSocketImpl(false)) { };142try (s) {143SocketImpl si = getSocketImpl(s);144assertTrue(si instanceof CustomSocketImpl);145}146}147148/**149* Test creating a Socket when there is a SocketImplFactory set.150*/151public void testNewSocket8() throws IOException {152setSocketSocketImplFactory(() -> new CustomSocketImpl(false));153try (Socket s = new Socket()) {154SocketImpl si = getSocketImpl(s);155assertTrue(si instanceof CustomSocketImpl);156} finally {157setSocketSocketImplFactory(null);158}159}160161/**162* Test creating a Socket for a DIRECT connection when there is a163* SocketImplFactory set.164*/165public void testNewSocket9() throws IOException {166setSocketSocketImplFactory(() -> new CustomSocketImpl(false));167try (Socket s = new Socket(Proxy.NO_PROXY)) {168SocketImpl si = getSocketImpl(s);169assertTrue(si instanceof CustomSocketImpl);170} finally {171setSocketSocketImplFactory(null);172}173}174175/**176* Test creating a Socket for a SOCKS connection when there is a177* SocketImplFactory set.178*/179public void testNewSocket10() throws IOException {180var address = new InetSocketAddress("127.0.0.1", 1080);181var socksProxy = new Proxy(Proxy.Type.SOCKS, address);182setSocketSocketImplFactory(() -> new CustomSocketImpl(false));183try (Socket s = new Socket(socksProxy)) {184SocketImpl si = getSocketImpl(s);185assertTrue(isSocksSocketImpl(si));186SocketImpl delegate = getDelegate(si);187assertTrue(isPlatformSocketImpl(delegate));188} finally {189setSocketSocketImplFactory(null);190}191}192193/**194* Test creating a Socket for a HTTP proxy connection when there is a195* SocketImplFactory set.196*/197public void testNewSocket11() throws IOException {198var address = new InetSocketAddress("127.0.0.1", 8080);199var httpProxy = new Proxy(Proxy.Type.HTTP, address);200setSocketSocketImplFactory(() -> new CustomSocketImpl(false));201try (Socket s = new Socket(httpProxy)) {202SocketImpl si = getSocketImpl(s);203assertTrue(isHttpConnectSocketImpl(si));204SocketImpl delegate = getDelegate(si);205assertTrue(isPlatformSocketImpl(delegate));206} finally {207setSocketSocketImplFactory(null);208}209}210211/**212* Test creating a Socket no SocketImpl when there is a SocketImplFactory set.213*/214public void testNewSocket12() throws IOException {215setSocketSocketImplFactory(() -> new CustomSocketImpl(false));216try {217Socket s = new Socket((SocketImpl) null) { };218try (s) {219assertTrue(getSocketImpl(s) == null);220s.bind(loopbackSocketAddress()); // force SocketImpl to be created221assertTrue(getSocketImpl(s) instanceof CustomSocketImpl);222}223} finally {224setSocketSocketImplFactory(null);225}226}227228/**229* Test creating an unbound ServerSocket, it should be created with a platform230* SocketImpl.231*/232public void testNewServerSocket1() throws IOException {233try (ServerSocket ss = new ServerSocket()) {234SocketImpl si = getSocketImpl(ss);235assertTrue(isPlatformSocketImpl(si));236}237}238239/**240* Test creating a bound ServerSocket, it should be created with a platform241* SocketImpl.242*/243public void testNewServerSocket2() throws IOException {244try (ServerSocket ss = new ServerSocket(0)) {245SocketImpl si = getSocketImpl(ss);246assertTrue(isPlatformSocketImpl(si));247}248}249250/**251* Test creating a ServerSocket with a custom SocketImpl.252*/253public void testNewServerSocket3() throws IOException {254ServerSocket ss = new ServerSocket(new CustomSocketImpl(true)) { };255try (ss) {256SocketImpl si = getSocketImpl(ss);257assertTrue(si instanceof CustomSocketImpl);258}259}260261/**262* Test creating an unbound ServerSocket when there is a SocketImplFactory set.263*/264public void testNewServerSocket4() throws IOException {265setServerSocketImplFactory(() -> new CustomSocketImpl(true));266try (ServerSocket ss = new ServerSocket()) {267SocketImpl si = getSocketImpl(ss);268assertTrue(si instanceof CustomSocketImpl);269} finally {270setServerSocketImplFactory(null);271}272}273274/**275* Test creating a bound ServerSocket when there is a SocketImplFactory set.276*/277public void testNewServerSocket5() throws IOException {278setServerSocketImplFactory(() -> new CustomSocketImpl(true));279try (ServerSocket ss = new ServerSocket(0)) {280SocketImpl si = getSocketImpl(ss);281assertTrue(si instanceof CustomSocketImpl);282} finally {283setServerSocketImplFactory(null);284}285}286287/**288* Test ServerSocket.accept. The ServerSocket uses a platform SocketImpl,289* the Socket to accept is created with no SocketImpl.290*/291public void testServerSocketAccept1() throws IOException {292var socket = new Socket((SocketImpl) null) { };293assertTrue(getSocketImpl(socket) == null);294295serverSocketAccept(socket, (ss, s) -> {296assertTrue(isPlatformSocketImpl(getSocketImpl(ss)));297assertTrue(s == socket);298SocketImpl si = getSocketImpl(s);299assertTrue(isPlatformSocketImpl(si));300checkFields(si);301});302}303304/**305* Test ServerSocket.accept. The ServerSocket uses a platform SocketImpl,306* the Socket to accept is created with no SocketImpl, and there is a custom307* client SocketImplFactory set.308*/309public void testServerSocketAccept2() throws IOException {310var socket = new Socket((SocketImpl) null) { };311assertTrue(getSocketImpl(socket) == null);312313serverSocketAccept(socket, () -> new CustomSocketImpl(false), (ss, s) -> {314assertTrue(isPlatformSocketImpl(getSocketImpl(ss)));315assertTrue(s == socket);316SocketImpl si = getSocketImpl(s);317assertTrue(isPlatformSocketImpl(si));318checkFields(si);319});320}321322/**323* Test ServerSocket.accept. The ServerSocket uses a platform SocketImpl,324* the Socket to accept is created with a SocketImpl that delegates to a325* platform SocketImpl.326*/327public void testServerSocketAccept3() throws IOException {328var socket = new Socket();329SocketImpl si = getSocketImpl(socket);330assertTrue(isSocksSocketImpl(si));331SocketImpl delegate = getDelegate(si);332assertTrue(isPlatformSocketImpl(delegate));333334serverSocketAccept(socket, (ss, s) -> {335assertTrue(isPlatformSocketImpl(getSocketImpl(ss)));336assertTrue(s == socket);337SocketImpl psi = getSocketImpl(socket);338assertTrue(isPlatformSocketImpl(psi));339checkFields(psi);340});341}342343/**344* Test ServerSocket.accept. The ServerSocket uses a platform SocketImpl,345* the Socket to accept is created with a custom SocketImpl.346*/347public void testServerSocketAccept4a() throws IOException {348SocketImpl clientImpl = new CustomSocketImpl(false);349Socket socket = new Socket(clientImpl) { };350assertTrue(getSocketImpl(socket) == clientImpl);351352try (ServerSocket ss = serverSocketToAccept(socket)) {353expectThrows(IOException.class, ss::accept);354} finally {355socket.close();356}357}358359public void testServerSocketAccept4b() throws IOException {360SocketImpl clientImpl = new CustomSocketImpl(false);361Socket socket = new Socket(clientImpl) { };362assertTrue(getSocketImpl(socket) == clientImpl);363364setSocketSocketImplFactory(() -> new CustomSocketImpl(false));365try (ServerSocket ss = serverSocketToAccept(socket)) {366expectThrows(IOException.class, ss::accept);367} finally {368setSocketSocketImplFactory(null);369socket.close();370}371}372373/**374* Test ServerSocket.accept. The ServerSocket uses a custom SocketImpl,375* the Socket to accept is created no SocketImpl.376*/377public void testServerSocketAccept5a() throws IOException {378SocketImpl serverImpl = new CustomSocketImpl(true);379try (ServerSocket ss = new ServerSocket(serverImpl) { }) {380ss.bind(loopbackSocketAddress());381expectThrows(IOException.class, ss::accept);382}383}384385public void testServerSocketAccept5b() throws IOException {386var socket = new Socket((SocketImpl) null) { };387assertTrue(getSocketImpl(socket) == null);388389SocketImpl serverImpl = new CustomSocketImpl(true);390try (ServerSocket ss = serverSocketToAccept(serverImpl, socket)) {391expectThrows(IOException.class, ss::accept);392} finally {393socket.close();394}395}396397public void testServerSocketAccept5c() throws IOException {398setServerSocketImplFactory(() -> new CustomSocketImpl(true));399try (ServerSocket ss = new ServerSocket(0)) {400expectThrows(IOException.class, ss::accept);401} finally {402setServerSocketImplFactory(null);403}404}405406public void testServerSocketAccept5d() throws IOException {407var socket = new Socket((SocketImpl) null) { };408assertTrue(getSocketImpl(socket) == null);409410setServerSocketImplFactory(() -> new CustomSocketImpl(true));411try (ServerSocket ss = serverSocketToAccept(socket)) {412expectThrows(IOException.class, ss::accept);413} finally {414setServerSocketImplFactory(null);415socket.close();416}417}418419/**420* Test ServerSocket.accept. The ServerSocket uses a custom SocketImpl,421* the Socket to accept is created with no SocketImpl, and there is a custom422* client SocketImplFactory set.423*/424public void testServerSocketAccept6() throws Exception {425var socket = new Socket((SocketImpl) null) { };426assertTrue(getSocketImpl(socket) == null);427428SocketImpl serverImpl = new CustomSocketImpl(true);429SocketImplFactory clientFactory = () -> new CustomSocketImpl(false);430serverSocketAccept(serverImpl, socket, clientFactory, (ss, s) -> {431assertTrue(getSocketImpl(ss) == serverImpl);432SocketImpl si = getSocketImpl(s);433assertTrue(si instanceof CustomSocketImpl);434checkFields(si);435});436}437438/**439* Test ServerSocket.accept. The ServerSocket uses a custom SocketImpl,440* the Socket to accept is created with a SocketImpl that delegates to a441* platform SocketImpl.442*/443public void testServerSocketAccept7a() throws IOException {444var socket = new Socket();445SocketImpl si = getSocketImpl(socket);446assertTrue(isSocksSocketImpl(si));447SocketImpl delegate = getDelegate(si);448assertTrue(isPlatformSocketImpl(delegate));449450SocketImpl serverImpl = new CustomSocketImpl(true);451try (ServerSocket ss = serverSocketToAccept(serverImpl, socket)) {452expectThrows(IOException.class, ss::accept);453} finally {454socket.close();455}456}457458public void testServerSocketAccept7b() throws IOException {459var socket = new Socket();460SocketImpl si = getSocketImpl(socket);461assertTrue(isSocksSocketImpl(si));462SocketImpl delegate = getDelegate(si);463assertTrue(isPlatformSocketImpl(delegate));464465setServerSocketImplFactory(() -> new CustomSocketImpl(true));466try (ServerSocket ss = serverSocketToAccept(socket)) {467expectThrows(IOException.class, ss::accept);468} finally {469setServerSocketImplFactory(null);470socket.close();471}472}473474/**475* Test ServerSocket.accept. The ServerSocket uses a custom SocketImpl,476* the Socket to accept is created with a custom SocketImpl.477*/478public void testServerSocketAccept8() throws Exception {479SocketImpl clientImpl = new CustomSocketImpl(false);480Socket socket = new Socket(clientImpl) { };481assertTrue(getSocketImpl(socket) == clientImpl);482483SocketImpl serverImpl = new CustomSocketImpl(true);484SocketImplFactory clientFactory = () -> new CustomSocketImpl(false);485serverSocketAccept(serverImpl, socket, clientFactory, (ss, s) -> {486assertTrue(getSocketImpl(ss) == serverImpl);487assertTrue(getSocketImpl(s) == clientImpl);488checkFields(clientImpl);489});490}491492/**493* Creates a ServerSocket that returns the given Socket from accept.494* The consumer is invoked with the server socket and the accepted socket.495*/496static void serverSocketAccept(Socket socket,497BiConsumer<ServerSocket, Socket> consumer)498throws IOException499{500Socket s1 = null;501Socket s2 = null;502try (ServerSocket ss = serverSocketToAccept(socket)) {503s1 = new Socket(ss.getInetAddress(), ss.getLocalPort());504s2 = ss.accept();505consumer.accept(ss, s2);506} finally {507if (s1 != null) s1.close();508if (s2 != null) s2.close();509}510}511512/**513* Creates a ServerSocket that returns the given Socket from accept. The514* given SocketImplFactory is set during the accept and the consumer is515* invoked when the server socket and the accepted socket.516*/517static void serverSocketAccept(Socket socket,518SocketImplFactory factory,519BiConsumer<ServerSocket, Socket> consumer)520throws IOException521{522Socket s1 = null;523Socket s2 = null;524try (ServerSocket ss = serverSocketToAccept(socket)) {525s1 = new Socket(ss.getInetAddress(), ss.getLocalPort());526setSocketSocketImplFactory(factory);527try {528s2 = ss.accept();529} finally {530setSocketSocketImplFactory(null);531}532consumer.accept(ss, s2);533} finally {534if (s1 != null) s1.close();535if (s2 != null) s2.close();536}537}538539/**540* Creates a ServerSocket with a SocketImpl returns the given Socket from541* accept. The given SocketImplFactory is set during the accept and the542* consumer is invoked when the server socket and the accepted socket.543*/544static void serverSocketAccept(SocketImpl impl,545Socket socket,546SocketImplFactory factory,547BiConsumer<ServerSocket, Socket> consumer)548throws IOException549{550Socket s1 = null;551Socket s2 = null;552try (ServerSocket ss = serverSocketToAccept(impl, socket)) {553s1 = new Socket(ss.getInetAddress(), ss.getLocalPort());554setSocketSocketImplFactory(factory);555try {556s2 = ss.accept();557} finally {558setSocketSocketImplFactory(null);559}560consumer.accept(ss, s2);561} finally {562if (s1 != null) s1.close();563if (s2 != null) s2.close();564}565}566567/**568* Returns a new InetSocketAddress with the loopback interface569* and port 0.570*/571static InetSocketAddress loopbackSocketAddress() {572InetAddress loopback = InetAddress.getLoopbackAddress();573return new InetSocketAddress(loopback, 0);574}575576/**577* Returns a ServerSocket bound to a port on the loopback address578*/579static ServerSocket boundServerSocket() throws IOException {580ServerSocket ss = new ServerSocket();581ss.bind(loopbackSocketAddress());582return ss;583}584585/**586* Creates a ServerSocket that returns the given Socket from accept.587*/588static ServerSocket serverSocketToAccept(Socket s) throws IOException {589ServerSocket ss = new ServerSocket() {590@Override591public Socket accept() throws IOException {592implAccept(s);593return s;594}595};596ss.bind(loopbackSocketAddress());597return ss;598}599600/**601* Creates a ServerSocket with a SocketImpl that returns the given Socket602* from accept.603*/604static ServerSocket serverSocketToAccept(SocketImpl impl, Socket s) throws IOException {605ServerSocket ss = new ServerSocket(impl) {606@Override607public Socket accept() throws IOException {608implAccept(s);609return s;610}611};612ss.bind(loopbackSocketAddress());613return ss;614}615616/**617* Returns the socket's SocketImpl618*/619static SocketImpl getSocketImpl(Socket s) {620try {621Field f = Socket.class.getDeclaredField("impl");622f.setAccessible(true);623return (SocketImpl) f.get(s);624} catch (Exception e) {625throw new RuntimeException(e);626}627}628629/**630* Returns the server socket's SocketImpl631*/632static SocketImpl getSocketImpl(ServerSocket ss) {633try {634Field f = ServerSocket.class.getDeclaredField("impl");635f.setAccessible(true);636return (SocketImpl) f.get(ss);637} catch (Exception e) {638throw new RuntimeException(e);639}640}641642/**643* Returns the SocketImpl that the given SocketImpl delegates to644*/645static SocketImpl getDelegate(SocketImpl si) {646try {647Class<?> clazz = Class.forName("java.net.DelegatingSocketImpl");648Field f = clazz.getDeclaredField("delegate");649f.setAccessible(true);650return (SocketImpl) f.get(si);651} catch (Exception e) {652throw new RuntimeException(e);653}654}655656/**657* Returns the value of a SocketImpl field658*/659static <T> T get(SocketImpl si, String name) {660try {661Field f = SocketImpl.class.getDeclaredField(name);662f.setAccessible(true);663return (T) f.get(si);664} catch (Exception e) {665throw new RuntimeException(e);666}667}668669/**670* Sets the value of SocketImpl field671*/672static void set(SocketImpl si, String name, Object value) {673try {674Field f = SocketImpl.class.getDeclaredField(name);675f.setAccessible(true);676f.set(si, value);677} catch (Exception e) {678throw new RuntimeException(e);679}680}681682/**683* Returns true if the SocketImpl is a PlatformSocketImpl684*/685static boolean isPlatformSocketImpl(SocketImpl si) {686try {687Class<?> clazz = Class.forName("sun.net.PlatformSocketImpl");688return clazz.isInstance(si);689} catch (Exception e) {690throw new RuntimeException(e);691}692}693694/**695* Returns true if the SocketImpl is a SocksSocketImpl696*/697static boolean isSocksSocketImpl(SocketImpl si) {698try {699Class<?> clazz = Class.forName("java.net.SocksSocketImpl");700return clazz.isInstance(si);701} catch (Exception e) {702throw new RuntimeException(e);703}704}705706/**707* Returns true if the SocketImpl is a HttpConnectSocketImpl708*/709static boolean isHttpConnectSocketImpl(SocketImpl si) {710try {711Class<?> clazz = Class.forName("java.net.HttpConnectSocketImpl");712return clazz.isInstance(si);713} catch (Exception e) {714throw new RuntimeException(e);715}716}717718/**719* Socket.setSocketImplFactory(SocketImplFactory)720*/721static void setSocketSocketImplFactory(SocketImplFactory factory) {722try {723Field f = Socket.class.getDeclaredField("factory");724f.setAccessible(true);725f.set(null, factory);726} catch (Exception e) {727throw new RuntimeException(e);728}729}730731/**732* ServerSocket.setSocketFactory(SocketImplFactory)733*/734static void setServerSocketImplFactory(SocketImplFactory factory) {735try {736Field f = ServerSocket.class.getDeclaredField("factory");737f.setAccessible(true);738f.set(null, factory);739} catch (Exception e) {740throw new RuntimeException(e);741}742}743744/**745* Checks the 4 protected fields of a SocketImpl to make sure that they746* have been initialized.747*/748static void checkFields(SocketImpl si) {749FileDescriptor fd = get(si, "fd");750InetAddress address = get(si, "address");751int port = get(si, "port");752int localport = get(si, "localport");753assertTrue(fd.valid() && address != null && port != 0 && localport != 0);754}755756/**757* Custom SocketImpl that is layed on a SocketChannel or ServerSocketChannel758*/759static class CustomSocketImpl extends SocketImpl {760private final boolean server;761private ServerSocketChannel ssc;762private SocketChannel sc;763764CustomSocketImpl(boolean server) {765this.server = server;766}767768@Override769protected void create(boolean stream) throws IOException {770if (server) {771ssc = ServerSocketChannel.open();772} else {773sc = SocketChannel.open();774}775}776777@Override778protected void connect(String host, int port) throws IOException {779connect(new InetSocketAddress(host, port), 0);780}781782@Override783protected void connect(InetAddress address, int port) throws IOException {784connect(new InetSocketAddress(address, port), 0);785}786787@Override788protected void connect(SocketAddress remote, int timeout) throws IOException {789sc.connect(remote);790super.address = ((InetSocketAddress) remote).getAddress();791super.port = ((InetSocketAddress) remote).getPort();792}793794@Override795protected void bind(InetAddress address, int port) throws IOException {796if (server) {797ssc.bind(new InetSocketAddress(address, port));798super.localport = ssc.socket().getLocalPort();799} else {800sc.bind(new InetSocketAddress(address, port));801super.localport = sc.socket().getLocalPort();802}803super.address = address;804}805806@Override807protected void listen(int backlog) {808// do nothing809}810811@Override812protected void accept(SocketImpl si) throws IOException {813SocketChannel peer = ssc.accept();814FileDescriptor fd;815try {816Class<?> clazz = Class.forName("sun.nio.ch.SocketChannelImpl");817Field f = clazz.getDeclaredField("fd");818f.setAccessible(true);819fd = (FileDescriptor) f.get(peer);820} catch (Exception e) {821throw new RuntimeException(e);822}823set(si, "fd", fd);824set(si, "address", peer.socket().getInetAddress());825set(si, "port", peer.socket().getPort());826set(si, "localport", peer.socket().getLocalPort());827}828829@Override830protected InputStream getInputStream() {831throw new RuntimeException();832}833834@Override835protected OutputStream getOutputStream() {836throw new RuntimeException();837}838839@Override840protected int available() {841return 0;842}843844@Override845protected void close() {846}847848@Override849protected void sendUrgentData(int data) {850throw new RuntimeException();851}852853@Override854public void setOption(int option, Object value) {855throw new RuntimeException();856}857858@Override859public Object getOption(int option) {860throw new RuntimeException();861}862}863}864865866