001    /*
002     * Copyright (c) 2003, The Regents of the University of California, through
003     * Lawrence Berkeley National Laboratory (subject to receipt of any required
004     * approvals from the U.S. Dept. of Energy). All rights reserved.
005     */
006    package gov.lbl.dsd.sea.nio.util;
007    
008    import java.net.Socket;
009    import java.net.SocketException;
010    import java.net.SocketOptions;
011    import java.util.HashMap;
012    import java.util.Map;
013    
014    /**
015     * Convenience class to get and set socket options; see {@link SocketOptions}
016     * and {@link Socket}for the corresponding keys and values.
017     * <p>
018     * For TCP performance tuning, see http://dsd.lbl.gov/TCP-tuning/ and in particular
019     * http://dsd.lbl.gov/TCP-tuning/buffers.html for how to increase the max socket
020     * buffer sizes allowed by the operating system (for MacOSX use the FreeBSD
021     * instructions as root user). Further useful information: 
022     * http://www.psc.edu/networking/perf_tune.html
023     * 
024     * @author whoschek@lbl.gov
025     * @author $Author: hoschek3 $
026     * @version $Revision: 1.3 $, $Date: 2004/05/31 22:09:11 $
027     */
028    public class SocketOpts implements SocketOptions, java.io.Serializable {
029    
030            protected Map options;
031            
032            /**
033             * Creates an empty object (with all options yet undefined).
034             */
035            public SocketOpts() {
036                    this.options = new HashMap();
037            }
038    
039            /**
040             * Constructs and object containing the options of the given socket.
041             */
042            public SocketOpts(Socket socket) throws SocketException {
043                    this();
044                    setOption(SO_KEEPALIVE, new Boolean(socket.getKeepAlive()));
045                    setOption(SO_OOBINLINE, new Boolean(socket.getOOBInline()));
046                    setOption(SO_REUSEADDR, new Boolean(socket.getReuseAddress()));
047                    setOption(TCP_NODELAY, new Boolean(socket.getTcpNoDelay()));
048                    setOption(SO_RCVBUF, new Integer(socket.getReceiveBufferSize()));
049                    setOption(SO_SNDBUF, new Integer(socket.getSendBufferSize()));
050                    setOption(SO_LINGER, new Integer(socket.getSoLinger()));
051                    setOption(SO_TIMEOUT, new Integer(socket.getSoTimeout()));
052                    setOption(IP_TOS, new Integer(socket.getTrafficClass()));
053            }
054    
055            /** 
056             * Sets the given option to the given value.
057             * @see java.net.SocketOptions#setOption(int, java.lang.Object)
058             */
059            public void setOption(int optID, Object value) {
060                    this.options.put(new Integer(optID), value);
061            }
062    
063            /**
064             * Returns the given option
065             * @see java.net.SocketOptions#getOption(int)
066             */
067            public Object getOption(int optID) {
068                    return this.options.get(new Integer(optID));
069            }
070    
071            /**
072             * Copies the options from this object to the given socket.
073             */
074            public void copyTo(Socket socket) throws SocketException {
075                    if (getOption(SO_KEEPALIVE) != null) 
076                            socket.setKeepAlive(( (Boolean) getOption(SO_KEEPALIVE)).booleanValue());
077                    if (getOption(SO_OOBINLINE) != null) 
078                            socket.setOOBInline(( (Boolean) getOption(SO_OOBINLINE)).booleanValue());
079                    if (getOption(SO_REUSEADDR) != null) 
080                            socket.setReuseAddress(( (Boolean) getOption(SO_REUSEADDR)).booleanValue());
081                    if (getOption(TCP_NODELAY) != null) 
082                            socket.setTcpNoDelay(( (Boolean) getOption(TCP_NODELAY)).booleanValue());
083                    if (getOption(SO_RCVBUF) != null) 
084                            socket.setReceiveBufferSize(( (Integer) getOption(SO_RCVBUF)).intValue());
085                    if (getOption(SO_SNDBUF) != null) 
086                            socket.setSendBufferSize(( (Integer) getOption(SO_SNDBUF)).intValue());
087                    if (getOption(SO_LINGER) != null) 
088                            socket.setSoLinger(true, ( (Integer) getOption(SO_LINGER)).intValue());
089                    if (getOption(SO_TIMEOUT) != null) 
090                            socket.setSoTimeout(( (Integer) getOption(SO_TIMEOUT)).intValue());
091                    if (getOption(IP_TOS) != null) 
092                            socket.setTrafficClass(( (Integer) getOption(IP_TOS)).intValue());
093            }
094            
095            /** 
096             * Returns a detailed string representation of the receiver.
097             */
098            public String toString() {
099                    String s = this.getClass().getName() + " [";
100                    s += "SO_KEEPALIVE=" + getOption(SO_KEEPALIVE);
101                    s += ", SO_OOBINLINE=" + getOption(SO_OOBINLINE);
102                    s += ", SO_REUSEADDR=" + getOption(SO_REUSEADDR);
103                    s += ", TCP_NODELAY=" + getOption(TCP_NODELAY);
104                    s += ", SO_RCVBUF=" + getOption(SO_RCVBUF);
105                    s += ", SO_SNDBUF=" + getOption(SO_SNDBUF);
106                    s += ", SO_LINGER=" + getOption(SO_LINGER);
107                    s += ", SO_TIMEOUT=" + getOption(SO_TIMEOUT);
108                    s += ", IP_TOS=" + getOption(IP_TOS);
109                    s += "]";
110                    return s;
111            }
112                            
113    }