pipes-network-0.1.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.

This module re-exports many functions from Network.Simple.TCP module in the network-simple package. You might refer to that module for more documentation.

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.

serve

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 manually if you use this function.

serveFork

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 manually if you use this function.

Listening

listen

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. The NoDelay and ReuseAddr options are set on the socket.

Accepting

accept

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.

acceptFork

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.

connect

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.

Exports

data HostPreference

Preferred host to bind.

Constructors

HostAny

Any available host.

HostIPv4

Any available IPv4 host.

HostIPv6

Any available 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.