network-socket-options-0.2: Type-safe, portable alternative to getSocketOption/setSocketOption

Maintainerjoeyadams3.14159@gmail.com
Safe HaskellSafe-Infered

Network.Socket.Options

Contents

Description

Documentation is currently lacking. For now, see man 7 socket and man 7 tcp of the Linux man-pages, or look up setsockopt in MSDN.

Synopsis

Getting options

getAcceptConn :: HasSocket sock => sock -> IO BoolSource

This option is get-only.

getBroadcast :: HasSocket sock => sock -> IO BoolSource

getDebug :: HasSocket sock => sock -> IO BoolSource

getDontRoute :: HasSocket sock => sock -> IO BoolSource

getError :: HasSocket sock => sock -> IO IntSource

This option is get-only.

getKeepAlive :: HasSocket sock => sock -> IO BoolSource

getOOBInline :: HasSocket sock => sock -> IO BoolSource

getRecvBuf :: HasSocket sock => sock -> IO IntSource

getReuseAddr :: HasSocket sock => sock -> IO BoolSource

getSendBuf :: HasSocket sock => sock -> IO IntSource

getType :: HasSocket sock => sock -> IO SocketTypeSource

This option is get-only.

TCP

Setting options

setBroadcast :: HasSocket sock => sock -> Bool -> IO ()Source

setDebug :: HasSocket sock => sock -> Bool -> IO ()Source

setDontRoute :: HasSocket sock => sock -> Bool -> IO ()Source

setKeepAlive :: HasSocket sock => sock -> Bool -> IO ()Source

setLinger :: HasSocket sock => sock -> Maybe Seconds -> IO ()Source

On Windows, the Seconds value is truncated to 16 bits. This means if a linger time of more than 65535 seconds (about 18.2 hours) is given, it will wrap around.

setOOBInline :: HasSocket sock => sock -> Bool -> IO ()Source

setRecvBuf :: HasSocket sock => sock -> Int -> IO ()Source

setRecvTimeout :: HasSocket sock => sock -> Microseconds -> IO ()Source

Note the following about timeout values:

  • A value of 0 or less means the operation will never time out
  • On Windows, the timeout is truncated to milliseconds, 32-bit. However, if the number of microseconds is from 1 to 999, it will be rounded up to one millisecond, to prevent it from being treated as "never time out".

setReuseAddr :: HasSocket sock => sock -> Bool -> IO ()Source

setSendBuf :: HasSocket sock => sock -> Int -> IO ()Source

TCP

setTcpNoDelay :: HasSocket sock => sock -> Bool -> IO ()Source

Types

class HasSocket a whereSource

The getters and setters in this module can be used not only on Sockets, but on raw Fds (file descriptors) as well.

Methods

getSocket :: a -> CIntSource

Setting socket timeouts

The following functions are provided to work around a problem with network IO on Windows. They are no-ops on other systems. Use them in addition to, not instead of, asynchronous exceptions (e.g. System.Timeout) to time out network operations.

The problem is that GHC currently does not have proper IO manager support for Windows. On Unix, GHC uses non-blocking IO and select/epoll/kqueue for efficient multiplexing. On Windows, it uses blocking FFI (foreign function interface) calls. An FFI call blocks the OS thread it is called from, and cannot be interrupted by an asynchronous exception. This means that if a send or receive operation hangs indefinitely, the thread hangs indefinitely, and cannot be killed. Thus, the following timeout will not work on Windows, in a program compiled with -threaded:

timeout 120000000 $ recv sock len

In a program compiled without -threaded, the timeout will work, but it will leak an OS thread until data arrives on the socket.

We can work around the problem by performing the IO in another thread:

wrappedRecv :: Socket -> Int -> IO String
wrappedRecv sock len = do
    mv <- newEmptyMVar
    bracket (forkIO $ recv sock len >>= putMVar mv)
            (forkIO . killThread)
               -- Call 'killThread' in a forked thread, as it will block until
               -- the exception has been delivered to the target thread.
            (\_ -> takeMVar mv)

This will behave correctly, but it will leak an OS thread if recv hangs indefinitely. If about 1000 OS threads are hung on recv calls, the program will run out of address space and crash (assuming 32-bit Windows, with default settings).

Socket timeouts can be used to work around the problem. In a program compiled for Windows with -threaded, when a receive or send operation times out, it will fail with an exception, and will not leak an OS thread. Without -threaded, it will leak an OS thread, unfortunately.

Socket timeouts have no effect on connect, which does seem to time out on its own at some point. They also have no effect for hWaitForInput when an explicit timeout is given.

setSocketTimeoutsSource

Arguments

:: HasSocket sock 
=> sock 
-> Microseconds

Receive timeout

-> Microseconds

Send timeout

-> IO () 

On Windows, set the socket's SO_RCVTIMEO and SO_SNDTIMEO values to the ones given. On other platforms, do nothing.

setHandleTimeoutsSource

Arguments

:: Handle 
-> Microseconds

Receive timeout

-> Microseconds

Send timeout

-> IO () 

On Windows, set timeouts for a socket that has already been wrapped in a Handle by connectTo or accept. On other platforms, do nothing.