Maintainer | joeyadams3.14159@gmail.com |
---|---|
Safe Haskell | None |
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.
- getAcceptConn :: HasSocket sock => sock -> IO Bool
- getBroadcast :: HasSocket sock => sock -> IO Bool
- getDebug :: HasSocket sock => sock -> IO Bool
- getDontRoute :: HasSocket sock => sock -> IO Bool
- getError :: HasSocket sock => sock -> IO Int
- getKeepAlive :: HasSocket sock => sock -> IO Bool
- getLinger :: HasSocket sock => sock -> IO (Maybe Seconds)
- getOOBInline :: HasSocket sock => sock -> IO Bool
- getRecvBuf :: HasSocket sock => sock -> IO Int
- getRecvTimeout :: HasSocket sock => sock -> IO Microseconds
- getReuseAddr :: HasSocket sock => sock -> IO Bool
- getSendBuf :: HasSocket sock => sock -> IO Int
- getSendTimeout :: HasSocket sock => sock -> IO Microseconds
- getType :: HasSocket sock => sock -> IO SocketType
- getTcpNoDelay :: HasSocket sock => sock -> IO Bool
- setBroadcast :: HasSocket sock => sock -> Bool -> IO ()
- setDebug :: HasSocket sock => sock -> Bool -> IO ()
- setDontRoute :: HasSocket sock => sock -> Bool -> IO ()
- setKeepAlive :: HasSocket sock => sock -> Bool -> IO ()
- setLinger :: HasSocket sock => sock -> Maybe Seconds -> IO ()
- setOOBInline :: HasSocket sock => sock -> Bool -> IO ()
- setRecvBuf :: HasSocket sock => sock -> Int -> IO ()
- setRecvTimeout :: HasSocket sock => sock -> Microseconds -> IO ()
- setReuseAddr :: HasSocket sock => sock -> Bool -> IO ()
- setSendBuf :: HasSocket sock => sock -> Int -> IO ()
- setSendTimeout :: HasSocket sock => sock -> Microseconds -> IO ()
- setTcpNoDelay :: HasSocket sock => sock -> Bool -> IO ()
- class HasSocket a where
- type Seconds = Int
- type Microseconds = Int64
- setSocketTimeouts :: HasSocket sock => sock -> Microseconds -> Microseconds -> IO ()
- setHandleTimeouts :: Handle -> Microseconds -> Microseconds -> IO ()
Getting options
getAcceptConn :: HasSocket sock => sock -> IO BoolSource
This option is get-only.
getBroadcast :: HasSocket sock => sock -> IO BoolSource
getDontRoute :: HasSocket sock => sock -> IO BoolSource
getKeepAlive :: HasSocket sock => sock -> IO BoolSource
getOOBInline :: HasSocket sock => sock -> IO BoolSource
getRecvBuf :: HasSocket sock => sock -> IO IntSource
getRecvTimeout :: HasSocket sock => sock -> IO MicrosecondsSource
getReuseAddr :: HasSocket sock => sock -> IO BoolSource
getSendBuf :: HasSocket sock => sock -> IO IntSource
getSendTimeout :: HasSocket sock => sock -> IO MicrosecondsSource
getType :: HasSocket sock => sock -> IO SocketTypeSource
This option is get-only.
TCP
getTcpNoDelay :: HasSocket sock => sock -> IO BoolSource
Setting options
setBroadcast :: 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
setSendTimeout :: HasSocket sock => sock -> Microseconds -> IO ()Source
TCP
setTcpNoDelay :: HasSocket sock => sock -> Bool -> IO ()Source
Types
type Microseconds = Int64Source
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.
:: 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.
:: Handle | |
-> Microseconds | Receive timeout |
-> Microseconds | Send timeout |
-> IO () |