network-2.3.1.0: Low-level networking interface

Portability | portable
Stability | provisional
Maintainer | libraries@haskell.org
Safe Haskell | None

Network.Socket

Contents

- Types
- Address operations
- Socket operations
  - Sending and receiving data
  - Predicates on sockets
- Socket options
- File descriptor transmission
- Special constants
- Initialisation
- Very low level operations
- Internal

Description

The Network.Socket module is for when you want full control over sockets. Essentially the entire C socket API is exposed through this module; in general the operations follow the behaviour of the C functions of the same name (consult your favourite Unix networking book).

A higher level interface to networking operations is provided through the module Network.

Synopsis

- data Socket = MkSocket CInt Family SocketType ProtocolNumber (MVar SocketStatus)
- data Family
  - = AF_UNSPEC
  - | AF_UNIX
  - | AF_INET
  - | AF_INET6
  - | AF_IMPLINK
  - | AF_PUP
  - | AF_CHAOS
  - | AF_NS
  - | AF_ECMA
  - | AF_DATAKIT
  - | AF_CCITT
  - | AF_SNA
  - | AF_DECnet
  - | AF_DLI
  - | AF_LAT
  - | AF_HYLINK
  - | AF_APPLETALK
  - | AF_ROUTE
  - | AF_ISO
  - | AF_OSI
  - | AF_IPX
  - | AF_COIP
  - | AF_CNT
  - | AF_SIP
  - | AF_ISDN
  - | AF_NATM
  - | AF_ENCAP
  - | AF_LINK
  - | AF_BLUETOOTH
- data SocketType
  - = NoSocketType
  - | Stream
  - | Datagram
  - | Raw
  - | RDM
  - | SeqPacket
- data SockAddr
  - = SockAddrInet PortNumber HostAddress
  - | SockAddrInet6 PortNumber FlowInfo HostAddress6 ScopeID
  - | SockAddrUnix String
- data SocketStatus
  - = NotConnected
  - | Bound
  - | Listening
  - | Connected
  - | ConvertedToHandle
  - | Closed
- type HostAddress = Word32
- type HostAddress6 = (Word32, Word32, Word32, Word32)
- type FlowInfo = Word32
- type ScopeID = Word32
- data ShutdownCmd
  - = ShutdownReceive
  - | ShutdownSend
  - | ShutdownBoth
- type ProtocolNumber = CInt
- defaultProtocol :: ProtocolNumber
- newtype PortNumber = PortNum Word16
- type HostName = String
- type ServiceName = String
- data AddrInfo = AddrInfo {
  - addrFlags :: [AddrInfoFlag]
  - addrFamily :: Family
  - addrSocketType :: SocketType
  - addrProtocol :: ProtocolNumber
  - addrAddress :: SockAddr
  - addrCanonName :: Maybe String
  }
- data AddrInfoFlag
  - = AI_ADDRCONFIG
  - | AI_ALL
  - | AI_CANONNAME
  - | AI_NUMERICHOST
  - | AI_NUMERICSERV
  - | AI_PASSIVE
  - | AI_V4MAPPED
- addrInfoFlagImplemented :: AddrInfoFlag -> Bool
- defaultHints :: AddrInfo
- getAddrInfo :: Maybe AddrInfo -> Maybe HostName -> Maybe ServiceName -> IO [AddrInfo]
- data NameInfoFlag
  - = NI_DGRAM
  - | NI_NAMEREQD
  - | NI_NOFQDN
  - | NI_NUMERICHOST
  - | NI_NUMERICSERV
- getNameInfo :: [NameInfoFlag] -> Bool -> Bool -> SockAddr -> IO (Maybe HostName, Maybe ServiceName)
- socket :: Family -> SocketType -> ProtocolNumber -> IO Socket
- socketPair :: Family -> SocketType -> ProtocolNumber -> IO (Socket, Socket)
- connect :: Socket -> SockAddr -> IO ()
- bindSocket :: Socket -> SockAddr -> IO ()
- listen :: Socket -> Int -> IO ()
- accept :: Socket -> IO (Socket, SockAddr)
- getPeerName :: Socket -> IO SockAddr
- getSocketName :: Socket -> IO SockAddr
- getPeerCred :: Socket -> IO (CUInt, CUInt, CUInt)
- socketPort :: Socket -> IO PortNumber
- socketToHandle :: Socket -> IOMode -> IO Handle
- sendTo :: Socket -> String -> SockAddr -> IO Int
- sendBufTo :: Socket -> Ptr a -> Int -> SockAddr -> IO Int
- recvFrom :: Socket -> Int -> IO (String, Int, SockAddr)
- recvBufFrom :: Socket -> Ptr a -> Int -> IO (Int, SockAddr)
- send :: Socket -> String -> IO Int
- recv :: Socket -> Int -> IO String
- recvLen :: Socket -> Int -> IO (String, Int)
- inet_addr :: String -> IO HostAddress
- inet_ntoa :: HostAddress -> IO String
- shutdown :: Socket -> ShutdownCmd -> IO ()
- sClose :: Socket -> IO ()
- sIsConnected :: Socket -> IO Bool
- sIsBound :: Socket -> IO Bool
- sIsListening :: Socket -> IO Bool
- sIsReadable :: Socket -> IO Bool
- sIsWritable :: Socket -> IO Bool
- data SocketOption
  - = DummySocketOption__
  - | Debug
  - | ReuseAddr
  - | Type
  - | SoError
  - | DontRoute
  - | Broadcast
  - | SendBuffer
  - | RecvBuffer
  - | KeepAlive
  - | OOBInline
  - | TimeToLive
  - | MaxSegment
  - | NoDelay
  - | Linger
  - | ReusePort
  - | RecvLowWater
  - | SendLowWater
  - | RecvTimeOut
  - | SendTimeOut
  - | UseLoopBack
  - | IPv6Only
- getSocketOption :: Socket -> SocketOption -> IO Int
- setSocketOption :: Socket -> SocketOption -> Int -> IO ()
- sendFd :: Socket -> CInt -> IO ()
- recvFd :: Socket -> IO CInt
- sendAncillary :: Socket -> Int -> Int -> Int -> Ptr a -> Int -> IO ()
- recvAncillary :: Socket -> Int -> Int -> IO (Int, Int, Ptr a, Int)
- aNY_PORT :: PortNumber
- iNADDR_ANY :: HostAddress
- iN6ADDR_ANY :: HostAddress6
- sOMAXCONN :: Int
- sOL_SOCKET :: Int
- sCM_RIGHTS :: Int
- maxListenQueue :: Int
- withSocketsDo :: IO a -> IO a
- fdSocket :: Socket -> CInt
- mkSocket :: CInt -> Family -> SocketType -> ProtocolNumber -> SocketStatus -> IO Socket
- packFamily :: Family -> CInt
- unpackFamily :: CInt -> Family
- packSocketType :: SocketType -> CInt
- throwSocketErrorIfMinus1_ :: (Eq a, Num a) => String -> IO a -> IO ()

# Types

data Socket

Constructors

MkSocket CInt Family SocketType ProtocolNumber (MVar SocketStatus) |

Instances

Eq Socket |
Show Socket |
Typeable Socket |

data Family

This data type might have different constructors depending on what is supported by the operating system.

Constructors

AF_UNSPEC |
AF_UNIX |
AF_INET |
AF_INET6 |
AF_IMPLINK |
AF_PUP |
AF_CHAOS |
AF_NS |
AF_ECMA |
AF_DATAKIT |
AF_CCITT |
AF_SNA |
AF_DECnet |
AF_DLI |
AF_LAT |
AF_HYLINK |
AF_APPLETALK |
AF_ROUTE |
AF_ISO |
AF_OSI |
AF_IPX |
AF_COIP |
AF_CNT |
AF_SIP |
AF_ISDN |
AF_NATM |
AF_ENCAP |
AF_LINK |
AF_BLUETOOTH |

Instances

Eq Family |
Ord Family |
Read Family |
Show Family |

data SocketType

Socket Types.

This data type might have different constructors depending on what is supported by the operating system.

Constructors

NoSocketType |
Stream |
Datagram |
Raw |
RDM |
SeqPacket |

Instances

Eq SocketType |
Ord SocketType |
Read SocketType |
Show SocketType |
Typeable SocketType |

data SockAddr

Constructors

SockAddrInet PortNumber HostAddress |
SockAddrInet6 PortNumber FlowInfo HostAddress6 ScopeID |
SockAddrUnix String |

Instances

Eq SockAddr |
Show SockAddr |
Typeable SockAddr |

data SocketStatus

Constructors

NotConnected |
Bound |
Listening |
Connected |
ConvertedToHandle |
Closed |

Instances

Eq SocketStatus |
Show SocketStatus |
Typeable SocketStatus |

type HostAddress = Word32

Network byte order.

type HostAddress6 = (Word32, Word32, Word32, Word32)

Host byte order.

type FlowInfo = Word32

type ScopeID = Word32

data ShutdownCmd

Constructors

ShutdownReceive |
ShutdownSend |
ShutdownBoth |

Instances

Typeable ShutdownCmd |

type ProtocolNumber = CInt

defaultProtocol :: ProtocolNumber

This is the default protocol for a given service.

newtype PortNumber

Constructors

PortNum Word16 |

Instances

Enum PortNumber |
Eq PortNumber |
Integral PortNumber |
Num PortNumber |
Ord PortNumber |
Real PortNumber |
Show PortNumber |
Typeable PortNumber |
Storable PortNumber |

# Address operations

type HostName = String

Either a host name e.g., `"haskell.org"` or a numeric host address string consisting of a dotted decimal IPv4 address or an IPv6 address e.g., `"192.168.0.1"`.

type ServiceName = String

data AddrInfo

Constructors

AddrInfo |

Fields

addrFlags :: [AddrInfoFlag]
addrFamily :: Family
addrSocketType :: SocketType
addrProtocol :: ProtocolNumber
addrAddress :: SockAddr
addrCanonName :: Maybe String

Instances

Eq AddrInfo |
Show AddrInfo |
Typeable AddrInfo |
Storable AddrInfo |

data AddrInfoFlag

Flags that control the querying behaviour of `getAddrInfo`.

Constructors

AI_ADDRCONFIG |
AI_ALL |
AI_CANONNAME |
AI_NUMERICHOST |
AI_NUMERICSERV |
AI_PASSIVE |
AI_V4MAPPED |

Instances

Eq AddrInfoFlag |
Read AddrInfoFlag |
Show AddrInfoFlag |
Typeable AddrInfoFlag |

addrInfoFlagImplemented :: AddrInfoFlag -> Bool

Indicate whether the given `AddrInfoFlag` will have any effect on this system.

defaultHints :: AddrInfo

Default hints for address lookup with `getAddrInfo`. The values of the `addrAddress` and `addrCanonName` fields are `undefined`, and are never inspected by `getAddrInfo`.

getAddrInfo

Arguments

:: Maybe AddrInfo | preferred socket type or protocol
-> Maybe HostName | host name to look up
-> Maybe ServiceName | service name to look up
-> IO [AddrInfo] | resolved addresses, with best first

Resolve a host or service name to one or more addresses. The `AddrInfo` values that this function returns contain `SockAddr` values that you can pass directly to `connect` or `bindSocket`.

This function is protocol independent. It can return both IPv4 and IPv6 address information.

The `AddrInfo` argument specifies the preferred query behaviour, socket options, or protocol. You can override these conveniently using Haskell's record update syntax on `defaultHints`, for example as follows:

       myHints = defaultHints { addrFlags = [AI_ADDRCONFIG, AI_CANONNAME] }

Values for `addrFlags` control query behaviour. The supported flags are as follows:

`AI_PASSIVE`
  If no `HostName` value is provided, the network address in each `SockAddr` will be left as a wild card, i.e. as either `iNADDR_ANY` or `iN6ADDR_ANY`. This is useful for server applications that will accept connections from any client.
`AI_CANONNAME`
  The `addrCanonName` field of the first returned `AddrInfo` will contain the canonical name of the host.
`AI_NUMERICHOST`
  The `HostName` argument must be a numeric address in string form, and network name lookups will not be attempted.

Note: Although the following flags are required by RFC 3493, they may not have an effect on all platforms, because the underlying network stack may not support them. To see whether a flag from the list below will have any effect, call `addrInfoFlagImplemented`.

`AI_NUMERICSERV`
  The `ServiceName` argument must be a port number in string form, and service name lookups will not be attempted.
`AI_ADDRCONFIG`
  The list of returned `AddrInfo` values will only contain IPv4 addresses if the local system has at least one IPv4 interface configured, and likewise for IPv6.
`AI_V4MAPPED`
  If an IPv6 lookup is performed, and no IPv6 addresses are found, IPv6-mapped IPv4 addresses will be returned.
`AI_ALL`
  If `AI_ALL` is specified, return all matching IPv6 and IPv4 addresses. Otherwise, this flag has no effect.

You must provide a `Just` value for at least one of the `HostName` or `ServiceName` arguments. `HostName` can be either a numeric network address (dotted quad for IPv4, colon-separated hex for IPv6) or a hostname. In the latter case, its addresses will be looked up unless `AI_NUMERICHOST` is specified as a hint. If you do not provide a `HostName` value and do not set `AI_PASSIVE` as a hint, network addresses in the result will contain the address of the loopback interface.

If the query fails, this function throws an IO exception instead of returning an empty list. Otherwise, it returns a non-empty list of `AddrInfo` values.

There are several reasons why a query might result in several values. For example, the queried-for host could be multihomed, or the service might be available via several protocols.

Note: the order of arguments is slightly different to that defined for `getaddrinfo` in RFC 2553. The `AddrInfo` parameter comes first to make partial application easier.

Example: `let hints = defaultHints { addrFlags = [AI_ADDRCONFIG, AI_CANONNAME] } addrs <- getAddrInfo (Just hints) (Just www.haskell.org) (Just http) let addr = head addrs sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr) connect sock (addrAddress addr)`

data NameInfoFlag

Constructors

NI_DGRAM |
NI_NAMEREQD |
NI_NOFQDN |
NI_NUMERICHOST |
NI_NUMERICSERV |

Instances

Eq NameInfoFlag |
Read NameInfoFlag |
Show NameInfoFlag |
Typeable NameInfoFlag |

getNameInfo

Arguments

:: [NameInfoFlag] | flags to control lookup behaviour
-> Bool | whether to look up a hostname
-> Bool | whether to look up a service name
-> SockAddr | the address to look up
-> IO (Maybe HostName, Maybe ServiceName) |

Resolve an address to a host or service name. This function is protocol independent.

The list of `NameInfoFlag` values controls query behaviour. The supported flags are as follows:

`NI_NOFQDN`
  If a host is local, return only the hostname part of the FQDN.
`NI_NUMERICHOST`
  The name of the host is not looked up. Instead, a numeric representation of the host's address is returned. For an IPv4 address, this will be a dotted-quad string. For IPv6, it will be colon-separated hexadecimal.
`NI_NUMERICSERV`
  The name of the service is not looked up. Instead, a numeric representation of the service is returned.
`NI_NAMEREQD`
  If the hostname cannot be looked up, an IO error is thrown.
`NI_DGRAM`
  Resolve a datagram-based service name. This is required only for the few protocols that have different port numbers for their datagram-based versions than for their stream-based versions.

Hostname and service name lookups can be expensive. You can specify which lookups to perform via the two `Bool` arguments. If one of these is `False`, the corresponding value in the returned tuple will be `Nothing`, and no lookup will be performed.

If a host or service's name cannot be looked up, then the numeric form of the address or service will be returned.

If the query fails, this function throws an IO exception.

Example: `(hostName, _) <- getNameInfo [] True False myAddress`

# Socket operations

socket :: Family -> SocketType -> ProtocolNumber -> IO Socket

Create a new socket using the given address family, socket type and protocol number. The address family is usually `AF_INET`, `AF_INET6`, or `AF_UNIX`. The socket type is usually `Stream` or `Datagram`. The protocol number is usually `defaultProtocol`. If `AF_INET6` is used, the `IPv6Only` socket option is set to 0 so that both IPv4 and IPv6 can be handled with one socket.

socketPair :: Family -> SocketType -> ProtocolNumber -> IO (Socket, Socket)

Build a pair of connected socket objects using the given address family, socket type, and protocol number. Address family, socket type, and protocol number are as for the `socket` function above. Availability: Unix.

connect :: Socket -> SockAddr -> IO ()

Connect to a remote socket at address.

bindSocket :: Socket -> SockAddr -> IO ()

Bind the socket to an address. The socket must not already be bound. The `Family` passed to `bindSocket` must be the same as that passed to `socket`. If the special port number `aNY_PORT` is passed then the system assigns the next available use port.

listen :: Socket -> Int -> IO ()

Listen for connections made to the socket. The second argument specifies the maximum number of queued connections and should be at least 1; the maximum value is system-dependent (usually 5).

accept :: Socket -> IO (Socket, SockAddr)

Accept a connection. The socket must be bound to an address and listening for connections. The return value is a pair `(conn, address)` where `conn` is a new socket object usable to send and receive data on the connection, and `address` is the address bound to the socket on the other end of the connection.

getPeerName :: Socket -> IO SockAddr

getSocketName :: Socket -> IO SockAddr

getPeerCred :: Socket -> IO (CUInt, CUInt, CUInt)

Returns the processID, userID and groupID of the socket's peer.

Only available on platforms that support SO_PEERCRED on domain sockets.

socketPort :: Socket -> IO PortNumber

socketToHandle :: Socket -> IOMode -> IO Handle

Turns a Socket into an `Handle`. By default, the new handle is unbuffered. Use `hSetBuffering` to change the buffering.

Note that since a `Handle` is automatically closed by a finalizer when it is no longer referenced, you should avoid doing any more operations on the `Socket` after calling `socketToHandle`. To close the `Socket` after `socketToHandle`, call `hClose` on the `Handle`.

## Sending and receiving data

Do not use the `send` and `recv` functions defined in this module in new code, as they incorrectly represent binary data as a Unicode string. As a result, these functions are inefficient and may lead to bugs in the program. Instead use the `send` and `recv` functions defined in the `ByteString` module.

sendTo :: Socket -> String -> SockAddr -> IO Int

Send data to the socket. The recipient can be specified explicitly, so the socket need not be in a connected state. Returns the number of bytes sent. Applications are responsible for ensuring that all data has been sent.

NOTE: blocking on Windows unless you compile with -threaded (see GHC ticket #1129)

sendBufTo :: Socket -> Ptr a -> Int -> SockAddr -> IO Int

Send data to the socket. The recipient can be specified explicitly, so the socket need not be in a connected state. Returns the number of bytes sent. Applications are responsible for ensuring that all data has been sent.

recvFrom :: Socket -> Int -> IO (String, Int, SockAddr)

Receive data from the socket. The socket need not be in a connected state. Returns `(bytes, nbytes, address)` where `bytes` is a `String` of length `nbytes` representing the data received and `address` is a `SockAddr` representing the address of the sending socket.

NOTE: blocking on Windows unless you compile with -threaded (see GHC ticket #1129)

recvBufFrom :: Socket -> Ptr a -> Int -> IO (Int, SockAddr)

Receive data from the socket, writing it into buffer instead of creating a new string. The socket need not be in a connected state. Returns `(nbytes, address)` where `nbytes` is the number of bytes received and `address` is a `SockAddr` representing the address of the sending socket.

NOTE: blocking on Windows unless you compile with -threaded (see GHC ticket #1129)

send :: Socket -> String -> IO Int

Send data to the socket. The socket must be connected to a remote socket. Returns the number of bytes sent. Applications are responsible for ensuring that all data has been sent.

recv :: Socket -> Int -> IO String

Receive data from the socket. The socket must be in a connected state. This function may return fewer bytes than specified. If the message is longer than the specified length, it may be discarded depending on the type of socket. This function may block until a message arrives.

Considering hardware and network realities, the maximum number of bytes to receive should be a small power of 2, e.g., 4096.

For TCP sockets, a zero length return value means the peer has closed its half side of the connection.

recvLen :: Socket -> Int -> IO (String, Int)

inet_addr :: String -> IO HostAddress

inet_ntoa :: HostAddress -> IO String

shutdown :: Socket -> ShutdownCmd -> IO ()

Shut down one or both halves of the connection, depending on the second argument to the function. If the second argument is `ShutdownReceive`, further receives are disallowed. If it is `ShutdownSend`, further sends are disallowed. If it is `ShutdownBoth`, further sends and receives are disallowed.

sClose :: Socket -> IO ()

Close the socket. All future operations on the socket object will fail. The remote end will receive no more data (after queued data is flushed).

## Predicates on sockets

sIsConnected :: Socket -> IO Bool

sIsBound :: Socket -> IO Bool

sIsListening :: Socket -> IO Bool

sIsReadable :: Socket -> IO Bool

sIsWritable :: Socket -> IO Bool

# Socket options

data SocketOption

Constructors

DummySocketOption__ |
Debug |
ReuseAddr |
Type |
SoError |
DontRoute |
Broadcast |
SendBuffer |
RecvBuffer |
KeepAlive |
OOBInline |
TimeToLive |
MaxSegment |
NoDelay |
Linger |
ReusePort |
RecvLowWater |
SendLowWater |
RecvTimeOut |
SendTimeOut |
UseLoopBack |
IPv6Only |

Instances

Show SocketOption |
Typeable SocketOption |

getSocketOption :: Socket -> SocketOption -> IO Int

setSocketOption :: Socket -> SocketOption -> Int -> IO ()

# File descriptor transmission

sendFd :: Socket -> CInt -> IO ()

recvFd :: Socket -> IO CInt

sendAncillary :: Socket -> Int -> Int -> Int -> Ptr a -> Int -> IO ()

recvAncillary :: Socket -> Int -> Int -> IO (Int, Int, Ptr a, Int)

# Special constants

aNY_PORT :: PortNumber

iNADDR_ANY :: HostAddress

The IPv4 wild card address.

iN6ADDR_ANY :: HostAddress6

The IPv6 wild card address.

sOMAXCONN :: Int

sOL_SOCKET :: Int

sCM_RIGHTS :: Int

maxListenQueue :: Int

# Initialisation

withSocketsDo :: IO a -> IO a

On Windows operating systems, the networking subsystem has to be initialised using `withSocketsDo` before any networking operations can be used. eg.

     main = withSocketsDo $ do {...}

Although this is only strictly necessary on Windows platforms, it is harmless on other platforms, so for portability it is good practice to use it all the time.

# Very low level operations

fdSocket :: Socket -> CInt

mkSocket :: CInt -> Family -> SocketType -> ProtocolNumber -> SocketStatus -> IO Socket

# Internal

The following are exported ONLY for use in the BSD module and should not be used anywhere else.

packFamily :: Family -> CInt

unpackFamily :: CInt -> Family

packSocketType :: SocketType -> CInt

throwSocketErrorIfMinus1_

Arguments

:: (Eq a, Num a) |
=> String | textual description of the location
-> IO a | the `IO` operation to be executed
-> IO () |

Throw an `IOError` corresponding to the current socket error if the IO action returns a result of `-1`. Discards the result of the IO action after error handling.