pipes-network-0.1.0: Use network sockets together with the pipes library.

Safe HaskellNone

Control.Proxy.TCP

Contents

Description

This module exports functions that allow you to safely use Socket resources acquired and released outside a Proxy pipeline.

Instead, if want to safely acquire and release resources within the pipeline itself, then you should use the functions exported by Control.Proxy.TCP.Safe.

Synopsis

Server side

The following functions allow you to obtain and use Sockets useful to the server side of a TCP connection.

Here's how you could run a TCP server that handles in different threads each incoming connection to port 8000 at address 127.0.0.1:

 listen (Host "127.0.0.1") "8000" $ \(listeningSocket, listeningAddr) -> do
   putStrLn $ "Listening for incoming connections at " ++ show listeningAddr
   forever . acceptFork listeningSocket $ \(connectionSocket, remoteAddr) -> do
     putStrLn $ "Connection established from " ++ show remoteAddr
     -- now you may use connectionSocket as you please within this scope,
     -- possibly with any of the socketReadS, nsocketReadS or socketWriteD
     -- proxies explained below.

If you keep reading you'll discover there are different ways to achieve the same, some ways more general than others. The above one was just an example using a pretty general approach, you are encouraged to use simpler approaches such as serve if those suit your needs.

serveSource

Arguments

:: HostPreference

Preferred host to bind.

-> ServiceName

Service port to bind.

-> ((Socket, SockAddr) -> IO r)

Computation to run once an incoming connection is accepted. Takes the connection socket and remote end address.

-> IO r 

Start a TCP server that sequentially accepts and uses each incoming connection.

Both the listening and connection sockets are closed when done or in case of exceptions.

Note: You don't need to use listen nor accept if you use this function.

serveForkSource

Arguments

:: HostPreference

Preferred host to bind.

-> ServiceName

Service port to bind.

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

Computation to run in a different thread once an incoming connection is accepted. Takes the connection socket and remote end address.

-> IO () 

Start a TCP server that accepts incoming connections and uses them concurrently in different threads.

The listening and connection sockets are closed when done or in case of exceptions.

Note: You don't need to use listen nor acceptFork if you use this function.

Listening

listenSource

Arguments

:: HostPreference

Preferred host to bind.

-> ServiceName

Service port to bind.

-> ((Socket, SockAddr) -> IO r)

Computation taking the listening socket and the address it's bound to.

-> IO r 

Bind a TCP listening socket and use it.

The listening socket is closed when done or in case of exceptions.

If you prefer to acquire and close the socket yourself, then use bindSock and the listen and sClose functions from Network.Socket instead.

Note: maxListenQueue is tipically 128, which is too small for high performance servers. So, we use the maximum between maxListenQueue and 2048 as the default size of the listening queue.

Accepting

acceptSource

Arguments

:: Socket

Listening and bound socket.

-> ((Socket, SockAddr) -> IO b)

Computation to run once an incoming connection is accepted. Takes the connection socket and remote end address.

-> IO b 

Accept a single incoming connection and use it.

The connection socket is closed when done or in case of exceptions.

acceptForkSource

Arguments

:: Socket

Listening and bound socket.

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

Computation to run in a different thread once an incoming connection is accepted. Takes the connection socket and remote end address.

-> IO ThreadId 

Accept a single incoming connection and use it in a different thread.

The connection socket is closed when done or in case of exceptions.

Client side

The following functions allow you to obtain and use Sockets useful to the client side of a TCP connection.

Here's how you could run a TCP client:

 connect "www.example.org" "80" $ \(connectionSocket, remoteAddr) -> do
   putStrLn $ "Connection established to " ++ show remoteAddr
   -- now you may use connectionSocket as you please within this scope,
   -- possibly with any of the socketReadS, nsocketReadS or socketWriteD
   -- proxies explained below.

connectSource

Arguments

:: HostName

Server hostname.

-> ServiceName

Server service port.

-> ((Socket, SockAddr) -> IO r)

Computation taking the communication socket and the server address.

-> IO r 

Connect to a TCP server and use the connection.

The connection socket is closed when done or in case of exceptions.

If you prefer to acquire and close the socket yourself, then use connectSock and the sClose function from Network.Socket instead.

Socket streams

Once you have a connected Socket, you can use the following Proxys to interact with the other connection end using streams.

socketReadSSource

Arguments

:: Proxy p 
=> Int

Maximum number of bytes to receive at once.

-> Socket

Connected socket.

-> () 
-> Producer p ByteString IO () 

Receives bytes from the remote end sends them downstream.

Less than the specified maximum number of bytes might be received at once.

If the remote peer closes its side of the connection, this proxy returns.

nsocketReadSSource

Arguments

:: Proxy p 
=> Socket

Connected socket.

-> Int 
-> Server p Int ByteString IO () 

Just like socketReadS, except each request from downstream specifies the maximum number of bytes to receive.

socketWriteDSource

Arguments

:: Proxy p 
=> Socket

Connected socket.

-> x 
-> p x ByteString x ByteString IO r 

Sends to the remote end the bytes received from upstream, then forwards such same bytes downstream.

Requests from downstream are forwarded upstream.

Timeouts

These proxies behave like the similarly named ones above, except support for timing out the interaction with the remote end is added.

socketReadTimeoutSSource

Arguments

:: Proxy p 
=> Int

Timeout in microseconds (1/10^6 seconds).

-> Int

Maximum number of bytes to receive at once.

-> Socket

Connected socket.

-> () 
-> Producer (EitherP Timeout p) ByteString IO () 

Like socketReadS, except it throws a Timeout exception in the EitherP proxy transformer if receiving data from the remote end takes more time than specified.

nsocketReadTimeoutSSource

Arguments

:: Proxy p 
=> Int

Timeout in microseconds (1/10^6 seconds).

-> Socket

Connected socket.

-> Int 
-> Server (EitherP Timeout p) Int ByteString IO () 

Like nsocketReadS, except it throws a Timeout exception in the EitherP proxy transformer if receiving data from the remote end takes more time than specified.

socketWriteTimeoutDSource

Arguments

:: Proxy p 
=> Int

Timeout in microseconds (1/10^6 seconds).

-> Socket

Connected socket.

-> x 
-> EitherP Timeout p x ByteString x ByteString IO r 

Like socketWriteD, except it throws a Timeout exception in the EitherP proxy transformer if sending data to the remote end takes more time than specified.

Low level support

bindSock :: HostPreference -> ServiceName -> IO (Socket, SockAddr)Source

Obtain a Socket bound to the given host name and TCP service port.

The obtained Socket should be closed manually using sClose when it's not needed anymore.

Prefer to use listen if you will be listening on this socket and using it within a limited scope, and would like it to be closed immediately after its usage or in case of exceptions.

connectSock :: HostName -> ServiceName -> IO (Socket, SockAddr)Source

Obtain a Socket connected to the given host and TCP service port.

The obtained Socket should be closed manually using sClose when it's not needed anymore, otherwise you risk having the socket open for much longer than needed.

Prefer to use connect if you will be using the socket within a limited scope and would like it to be closed immediately after its usage or in case of exceptions.

Exports

data HostPreference Source

Preferred host to bind.

Constructors

HostAny

Any avaiable host.

HostIPv4

Any avaiable IPv4 host.

HostIPv6

Any avaiable IPv6 host.

Host HostName

An explicit host name.

Instances

Eq HostPreference 
Ord HostPreference 
Read HostPreference 
Show HostPreference 
IsString HostPreference

The following special values are recognized:

data Timeout Source

Exception thrown when a timeout has elapsed.

Constructors

Timeout String

Timeouted with an additional explanatory message.