## Socket Options in Java

### 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.
- SO_BINDADDR
  - Fetch the local address binding of a socket.
  - Valid for Socket, ServerSocket, DatagramSocket.
- SO_REUSEADDR
  - Enable reuse address for a socket.
  - Valid for Socket, ServerSocket, DatagramSocket.
- SO_BROADCAST
  - Enables a socket to send broadcast messages.
  - Valid for DatagramSocket.
- SO_SNDBUF
  - Set a hint the size of the underlying buffers for outgoing network I/O.
  - Valid for all sockets: Socket, ServerSocket, DatagramSocket.
- SO_RCVBUF
  - Get the size of the buffer actually used by the platform when receiving in data on this socket.
  - Valid for all sockets: Socket, ServerSocket, DatagramSocket.
- SO_KEEPALIVE
  - Turn on socket keepalive.
  - Valid for Socket.
- SO_OOBINLINE
  - Enable inline reception of TCP urgent data.
  - Valid for Socket.
- IP_MULTICAST_IF
  - Specify the outgoing interface for multicast packets (on multihomed hosts).
  - Valid for MulticastSockets.
- IP_MULTICAST_LOOP
  - Enables or disables local loopback of multicast datagrams.
  - Valid for MulticastSocket.
- IP_TOS
  - Sets the type-of-service or traffic class field in the IP header for a TCP or UDP socket.
  - Valid for Socket, DatagramSocket

### Fell by the wayside...

Some possible BSD options that are not supported in java:

- 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.