network-2.3.1.0: Low-level networking interface

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

Network

Contents

- Basic data types
- Initialisation
- Server-side connections
- Client-side connections
- Simple sending and receiving
- Miscellaneous
- Networking Issues
  - Buffering
  - Improving I/O Performance over sockets
  - `SIGPIPE`

Description

The Network interface is a "higher-level" interface to networking facilities, and it is recommended unless you need the lower-level interface in Network.Socket.

Synopsis

- data Socket
- data PortID
  - = Service String
  - | PortNumber PortNumber
  - | UnixSocket String
- type HostName = String
- data PortNumber
- withSocketsDo :: IO a -> IO a
- listenOn :: PortID -> IO Socket
- accept :: Socket -> IO (Handle, HostName, PortNumber)
- sClose :: Socket -> IO ()
- connectTo :: HostName -> PortID -> IO Handle
- sendTo :: HostName -> PortID -> String -> IO ()
- recvFrom :: HostName -> PortID -> IO String
- socketPort :: Socket -> IO PortID

# Basic data types

data Socket

Instances

Eq Socket |
Show Socket |
Typeable Socket |

data PortID

Constructors

Service String |
PortNumber PortNumber |
UnixSocket String |

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

data PortNumber

Instances

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

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

# Server-side connections

listenOn

Arguments

:: PortID | Port Identifier
-> IO Socket | Connected Socket

Creates the server side socket which has been bound to the specified port.

NOTE: To avoid the "Address already in use" problems popped up several times on the GHC-Users mailing list we set the `ReuseAddr` socket option on the listening socket. If you don't want this behaviour, please use the lower level `listen` instead.

If available, the `IPv6Only` socket option is set to 0 so that both IPv4 and IPv6 can be accepted with this socket.

accept

Arguments

:: Socket | Listening Socket
-> IO (Handle, HostName, PortNumber) | Triple of: read/write `Handle` for communicating with the client, the `HostName` of the peer socket, and the `PortNumber` of the remote connection.

Accept a connection on a socket created by `listenOn`. Normal I/O operations (see System.IO) can be used on the `Handle` returned to communicate with the client. Notice that although you can pass any Socket to Network.accept, only sockets of either AF_UNIX, AF_INET, or AF_INET6 will work (this shouldn't be a problem, though). When using AF_UNIX, HostName will be set to the path of the socket and PortNumber to -1.

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

# Client-side connections

connectTo :: HostName -> PortID -> IO Handle

Calling `connectTo` creates a client side socket which is connected to the given host and port. The Protocol and socket type is derived from the given port identifier. If a port number is given then the result is always an internet family `Stream` socket.

# Simple sending and receiving

Send and receive data from/to the given host and port number. These should normally only be used where the socket will not be required for further calls. Also, note that due to the use of `hGetContents` in `recvFrom` the socket will remain open (i.e. not available) even if the function already returned. Their use is strongly discouraged except for small test-applications or invocations from the command line.

sendTo :: HostName -> PortID -> String -> IO ()

recvFrom :: HostName -> PortID -> IO String

# Miscellaneous

socketPort :: Socket -> IO PortID

Returns the `PortID` associated with a given socket.

# Networking Issues

## Buffering

The `Handle` returned by `connectTo` and `accept` is block-buffered by default. For an interactive application you may want to set the buffering mode on the `Handle` to `LineBuffering` or `NoBuffering`, like so:

     h <- connectTo host port
     hSetBuffering h LineBuffering

## Improving I/O Performance over sockets

For really fast I/O, it might be worth looking at the `hGetBuf` and `hPutBuf` family of functions in System.IO.

## `SIGPIPE`

On Unix, when writing to a socket and the reading end is closed by the remote client, the program is normally sent a `SIGPIPE` signal by the operating system. The default behaviour when a `SIGPIPE` is received is to terminate the program silently, which can be somewhat confusing if you haven't encountered this before. The solution is to specify that `SIGPIPE` is to be ignored, using the POSIX library:

      import Posix
      main = do installHandler sigPIPE Ignore Nothing; ...