## Socket Options in Java

### javadoc's of socket classes for JDK1.1 are here!

### The C way

Programming in C, one sets options by using a system call along the lines of:

    	setsockopt(int fd, int level, int optval, void *optdata,
    		   int optdatalen);

    	fd = already opened (possibly connected) socket fd;
    	level = level in the protocol stack (IP, UDP, TCP) where
    	        the option applies;
    	optval = the option, a CONSTANT;
    	optdata = ptr to option dependent struct of parameters relevant
    	         only to a particular option;

### In java

The C way of setting options lacks the type-safety of object-oriented programming. The option one wishes to set/get is identified by an int, and the value to set/get into is an opaque void*. It is all too easy to pass the wrong option identifier, the wrong type object in the void* parameter, or the wrong for that parameter. Worse still, the code for these errors will typically compile, and the error will only be manifested at runtime.

Java now provides a type-safe way to set options. Each socket class has a get/set method for each option it supports, taking and returning the appropriate type. The options supported, for which socket classes and their meaning in brief:

- TCP_NODELAY
  - Disable Nagle's algorithm.
  - Valid for (client) Sockets.
- SO_LINGER
  - Specify a linger-on-close timeout.
  - Valid for (client) Sockets.
- SO_TIMEOUT
  - Specify a timeout on blocking socket operations. (Don't block forever!)
  - Valid for all sockets: Socket, ServerSocket, DatagramSocket.
- IP_MULTICAST_IF
  - Specify the outgoing interface for multicast packets (on multihomed hosts).
  - Valid for MulticastSockets.

Additionally, JDK1.1 provides new constructors to Socket, ServerSocket and DatagramSocket that allow the specification of a local address/port to which the socket should bind, and similarly these classes can divulge their local addresses.

Full javadoc's for the socket classes in JDK1.1 are provided here, including complete details on how to get/set all options. If there's other options you'd like to use from java tell us!

### Fell by the wayside...

Some possible BSD options that are not supported in java:

- SO_KEEPALIVE:
  With this option, the OS repeatedly pings the connection's peer to make sure it's still there. The conventional wisdom on this is that this functionality is best handled at the application level. The Host Requirements RFC specifies a ping interval of 2 hours, which is not practically useful.
- MSG_OOB:
  This is really an option one passes to a read() or recv() on a socket to read data marked out-of-band or "urgent" if it present, before in-band data. If we include this we should also include an option SO_OOBINLINE (below), but this doesn't seem to be needed. The real complication against this is that we'd also have to provide a symmetrical way to write OOB data, and again this hasn't been requested.
- SO_OOBINLINE:
  This option will inline OOB data, making it appear inline like "normal" data. It would work in conjunction with MSG_OOB.
- RAW/ICMP SOCKETS:
  The main argument in favor of this one seemed to be so people could write "ping" in java. Security nightmare. Must be root on UNIX machines.

### The implementation details...

...that you don't need to know, unless you subclass SocketImpl/DatagramSocketImpl. Every *Socket object has an underlying SocketImpl/DatagramSocketImpl that interfaces to native code. The Impl classes implement two methods to support options:

    	void setOption(int optID, Object val) throws SocketException;
    	Object getOption(int optID) throws SocketException;

that look much like C. These methods act as glue to the native methods, and ensure type safety before native methods are invoked.