network-2.4.2.3: Low-level networking interface

Copyright | (c) The University of Glasgow 2001
License | BSD-style (see the file libraries/network/LICENSE)
Maintainer | libraries@haskell.org
Stability | provisional
Portability | portable
Safe Haskell | None
Language | Haskell98

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 |

Instances

Eq PortID |
Show PortID |

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 |
Storable PortNumber |
Typeable * 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 | Listening Socket

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

`maxListenQueue` (typically 128) is specified to the listen queue. This is good enough for normal network servers but is too small for high performance servers.

To avoid the "Address already in use" problems, the `ReuseAddr` socket option is set on the listening socket.

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

If you don't like the behavior above, please use the lower level `listen` instead.

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