network-2.5.0.0: Low-level networking interface

Portabilityportable
Stabilityprovisional
Maintainerlibraries@haskell.org
Safe HaskellNone

Network

Contents

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

Basic data types

type HostName = StringSource

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

Initialisation

withSocketsDo :: IO a -> IO aSource

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

listenOnSource

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.

acceptSource

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 ()Source

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 HandleSource

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.

Miscellaneous

socketPort :: Socket -> IO PortIDSource

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