SocketAdaptor.java revision 51b1b6997fd3f980076b8081f7f1165ccc2a4008
151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it
651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as
751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation.  Oracle designates this
851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided
951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code.
1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT
1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that
1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code).
1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version
1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation,
1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any
2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions.
2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.nio.ch;
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.*;
2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.lang.ref.*;
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.net.*;
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.nio.*;
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.nio.channels.*;
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.AccessController;
3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.PrivilegedExceptionAction;
3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.*;
3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.misc.IoTrace;
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski// Make a socket channel look like a socket.
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski//
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski// The only aspects of java.net.Socket-hood that we don't attempt to emulate
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski// here are the interrupted-I/O exceptions (which our Solaris implementations
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski// attempt to support) and the sending of urgent data.  Otherwise an adapted
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski// socket should look enough like a real java.net.Socket to fool most of the
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski// developers most of the time, right down to the exception message strings.
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski//
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski// The methods in this class are defined in exactly the same order as in
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski// java.net.Socket so as to simplify tracking future changes to that class.
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski//
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class SocketAdaptor
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    extends Socket
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // The channel being adapted
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private final SocketChannelImpl sc;
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Timeout "option" value for reads
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private volatile int timeout = 0;
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private SocketAdaptor(SocketChannelImpl sc) throws SocketException {
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        super((SocketImpl) null);
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.sc = sc;
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static Socket create(SocketChannelImpl sc) {
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return new SocketAdaptor(sc);
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (SocketException e) {
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new InternalError("Should not reach here");
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public SocketChannel getChannel() {
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return sc;
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // Override this method just to protect against changes in the superclass
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    //
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void connect(SocketAddress remote) throws IOException {
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        connect(remote, 0);
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void connect(SocketAddress remote, int timeout) throws IOException {
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (remote == null)
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("connect: The address can't be null");
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (timeout < 0)
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("connect: timeout can't be negative");
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (sc.blockingLock()) {
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!sc.isBlocking())
9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new IllegalBlockingModeException();
9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            try {
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (timeout == 0) {
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    sc.connect(remote);
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return;
10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // Implement timeout with a selector
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                SelectionKey sk = null;
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Selector sel = null;
10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                sc.configureBlocking(false);
10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                try {
10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (sc.connect(remote))
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return;
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    sel = Util.getTemporarySelector(sc);
11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    sk = sc.register(sel, SelectionKey.OP_CONNECT);
11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    long to = timeout;
11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    for (;;) {
11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (!sc.isOpen())
11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            throw new ClosedChannelException();
11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        long st = System.currentTimeMillis();
11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        int ns = sel.select(to);
11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (ns > 0 &&
11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            sk.isConnectable() && sc.finishConnect())
11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            break;
12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        sel.selectedKeys().remove(sk);
12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        to -= System.currentTimeMillis() - st;
12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (to <= 0) {
12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            try {
12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                sc.close();
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            } catch (IOException x) { }
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            throw new SocketTimeoutException();
12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } finally {
13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (sk != null)
13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        sk.cancel();
13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (sc.isOpen())
13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        sc.configureBlocking(true);
13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (sel != null)
13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        Util.releaseTemporarySelector(sel);
13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } catch (Exception x) {
13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Net.translateException(x, true);
14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void bind(SocketAddress local) throws IOException {
14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            sc.bind(local);
14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (Exception x) {
14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Net.translateException(x);
15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public InetAddress getInetAddress() {
15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        SocketAddress remote = sc.remoteAddress();
15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (remote == null) {
15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return null;
15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return ((InetSocketAddress)remote).getAddress();
15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public InetAddress getLocalAddress() {
16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (sc.isOpen()) {
16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            InetSocketAddress local = sc.localAddress();
16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (local != null)
16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return Net.getRevealedLocalAddress(local).getAddress();
16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return new InetSocketAddress(0).getAddress();
16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int getPort() {
17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        SocketAddress remote = sc.remoteAddress();
17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (remote == null) {
17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return 0;
17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return ((InetSocketAddress)remote).getPort();
17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int getLocalPort() {
18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        SocketAddress local = sc.localAddress();
18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (local == null) {
18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return -1;
18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return ((InetSocketAddress)local).getPort();
18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private class SocketInputStream
19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        extends ChannelInputStream
19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        private SocketInputStream() {
19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            super(sc);
19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        protected int read(ByteBuffer bb)
19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throws IOException
19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        {
19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            synchronized (sc.blockingLock()) {
20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (!sc.isBlocking())
20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    throw new IllegalBlockingModeException();
20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (timeout == 0)
20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return sc.read(bb);
20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // Implement timeout with a selector
20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                SelectionKey sk = null;
20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Selector sel = null;
20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                sc.configureBlocking(false);
20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int n = 0;
21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Object traceContext = IoTrace.socketReadBegin();
21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                try {
21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ((n = sc.read(bb)) != 0)
21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return n;
21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    sel = Util.getTemporarySelector(sc);
21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    sk = sc.register(sel, SelectionKey.OP_READ);
21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    long to = timeout;
21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    for (;;) {
21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (!sc.isOpen())
21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            throw new ClosedChannelException();
22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        long st = System.currentTimeMillis();
22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        int ns = sel.select(to);
22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (ns > 0 && sk.isReadable()) {
22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            if ((n = sc.read(bb)) != 0)
22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                return n;
22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        sel.selectedKeys().remove(sk);
22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        to -= System.currentTimeMillis() - st;
22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (to <= 0)
22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            throw new SocketTimeoutException();
23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } finally {
23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    IoTrace.socketReadEnd(traceContext, getInetAddress(),
23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                          getPort(), timeout, n > 0 ? n : 0);
23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (sk != null)
23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        sk.cancel();
23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (sc.isOpen())
23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        sc.configureBlocking(true);
23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (sel != null)
23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        Util.releaseTemporarySelector(sel);
24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private InputStream socketInputStream = null;
24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public InputStream getInputStream() throws IOException {
24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!sc.isOpen())
25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!sc.isConnected())
25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is not connected");
25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!sc.isInputOpen())
25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket input is shutdown");
25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (socketInputStream == null) {
25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            try {
25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                socketInputStream = AccessController.doPrivileged(
25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    new PrivilegedExceptionAction<InputStream>() {
25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        public InputStream run() throws IOException {
26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            return new SocketInputStream();
26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    });
26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } catch (java.security.PrivilegedActionException e) {
26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw (IOException)e.getException();
26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return socketInputStream;
26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public OutputStream getOutputStream() throws IOException {
27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!sc.isOpen())
27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!sc.isConnected())
27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is not connected");
27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!sc.isOutputOpen())
27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket output is shutdown");
27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        OutputStream os = null;
27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            os = AccessController.doPrivileged(
28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                new PrivilegedExceptionAction<OutputStream>() {
28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    public OutputStream run() throws IOException {
28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return Channels.newOutputStream(sc);
28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                });
28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (java.security.PrivilegedActionException e) {
28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw (IOException)e.getException();
28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return os;
28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void setBooleanOption(SocketOption<Boolean> name, boolean value)
29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws SocketException
29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            sc.setOption(name, value);
29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (IOException x) {
29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Net.translateToSocketException(x);
29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void setIntOption(SocketOption<Integer> name, int value)
30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws SocketException
30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            sc.setOption(name, value);
30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (IOException x) {
30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Net.translateToSocketException(x);
30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private boolean getBooleanOption(SocketOption<Boolean> name) throws SocketException {
31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return sc.getOption(name).booleanValue();
31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (IOException x) {
31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Net.translateToSocketException(x);
31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return false;       // keep compiler happy
31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private int getIntOption(SocketOption<Integer> name) throws SocketException {
32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return sc.getOption(name).intValue();
32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (IOException x) {
32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Net.translateToSocketException(x);
32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return -1;          // keep compiler happy
32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setTcpNoDelay(boolean on) throws SocketException {
33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        setBooleanOption(StandardSocketOptions.TCP_NODELAY, on);
33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean getTcpNoDelay() throws SocketException {
33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return getBooleanOption(StandardSocketOptions.TCP_NODELAY);
33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setSoLinger(boolean on, int linger) throws SocketException {
33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!on)
33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            linger = -1;
34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        setIntOption(StandardSocketOptions.SO_LINGER, linger);
34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int getSoLinger() throws SocketException {
34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return getIntOption(StandardSocketOptions.SO_LINGER);
34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void sendUrgentData(int data) throws IOException {
34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (sc.blockingLock()) {
34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!sc.isBlocking())
35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new IllegalBlockingModeException();
35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int n = sc.sendOutOfBandData((byte)data);
35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            assert n == 1;
35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setOOBInline(boolean on) throws SocketException {
35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        setBooleanOption(ExtendedSocketOption.SO_OOBINLINE, on);
35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean getOOBInline() throws SocketException {
36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return getBooleanOption(ExtendedSocketOption.SO_OOBINLINE);
36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setSoTimeout(int timeout) throws SocketException {
36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (timeout < 0)
36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("timeout can't be negative");
36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.timeout = timeout;
36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int getSoTimeout() throws SocketException {
37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return timeout;
37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setSendBufferSize(int size) throws SocketException {
37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // size 0 valid for SocketChannel, invalid for Socket
37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (size <= 0)
37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("Invalid send size");
37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        setIntOption(StandardSocketOptions.SO_SNDBUF, size);
37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int getSendBufferSize() throws SocketException {
38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return getIntOption(StandardSocketOptions.SO_SNDBUF);
38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setReceiveBufferSize(int size) throws SocketException {
38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // size 0 valid for SocketChannel, invalid for Socket
38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (size <= 0)
38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("Invalid receive size");
38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        setIntOption(StandardSocketOptions.SO_RCVBUF, size);
39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int getReceiveBufferSize() throws SocketException {
39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return getIntOption(StandardSocketOptions.SO_RCVBUF);
39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setKeepAlive(boolean on) throws SocketException {
39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        setBooleanOption(StandardSocketOptions.SO_KEEPALIVE, on);
39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean getKeepAlive() throws SocketException {
40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return getBooleanOption(StandardSocketOptions.SO_KEEPALIVE);
40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setTrafficClass(int tc) throws SocketException {
40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        setIntOption(StandardSocketOptions.IP_TOS, tc);
40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int getTrafficClass() throws SocketException {
40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return getIntOption(StandardSocketOptions.IP_TOS);
41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setReuseAddress(boolean on) throws SocketException {
41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        setBooleanOption(StandardSocketOptions.SO_REUSEADDR, on);
41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean getReuseAddress() throws SocketException {
41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return getBooleanOption(StandardSocketOptions.SO_REUSEADDR);
41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void close() throws IOException {
42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        sc.close();
42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void shutdownInput() throws IOException {
42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            sc.shutdownInput();
42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (Exception x) {
42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Net.translateException(x);
42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void shutdownOutput() throws IOException {
43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            sc.shutdownOutput();
43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (Exception x) {
43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Net.translateException(x);
43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String toString() {
44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (sc.isConnected())
44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return "Socket[addr=" + getInetAddress() +
44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ",port=" + getPort() +
44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ",localport=" + getLocalPort() + "]";
44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return "Socket[unconnected]";
44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean isConnected() {
44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return sc.isConnected();
45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean isBound() {
45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return sc.localAddress() != null;
45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean isClosed() {
45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return !sc.isOpen();
45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean isInputShutdown() {
46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return !sc.isInputOpen();
46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean isOutputShutdown() {
46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return !sc.isOutputOpen();
46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
469