-- | -- Module : Streamly.Network.Socket -- Copyright : (c) 2018 Composewell Technologies -- -- License : BSD-3-Clause -- Maintainer : streamly@composewell.com -- Stability : released -- Portability : GHC -- -- This module provides Array and stream based socket operations to connect to -- remote hosts, to receive connections from remote hosts, and to read and -- write streams and arrays of bytes to and from network sockets. -- -- For basic socket types and operations please consult the @Network.Socket@ -- module of the <http://hackage.haskell.org/package/network network> package. -- -- = Examples -- -- To write a server, use the 'accept' unfold to start listening for -- connections from clients. 'accept' supplies a stream of connected sockets. -- We can map an effectful action on this socket stream to handle the -- connections. The action would typically use socket reading and writing -- operations to communicate with the remote host. We can read/write a stream -- of bytes or a stream of chunks of bytes ('Array'). -- -- Following is a short example of a concurrent echo server. Please note that -- this example can be written even more succinctly by using higher level -- operations from "Streamly.Network.Inet.TCP" module. -- -- @ -- {-\# LANGUAGE FlexibleContexts #-} -- -- import Data.Function ((&)) -- import Network.Socket -- import Streamly.Network.Socket (SockSpec(..)) -- -- import qualified Streamly.Prelude as Stream -- import qualified Streamly.Network.Socket as Socket -- -- main = do -- let spec = SockSpec -- { sockFamily = AF_INET -- , sockType = Stream -- , sockProto = defaultProtocol -- , sockOpts = [] -- } -- addr = SockAddrInet 8090 (tupleToHostAddress (0,0,0,0)) -- in server spec addr -- -- where -- -- server spec addr = -- Stream.unfold Socket.accept (maxListenQueue, spec, addr) -- ParallelT IO Socket -- & Stream.mapM (Socket.forSocketM echo) -- ParallelT IO () -- & Stream.fromParallel -- SerialT IO () -- & Stream.drain -- IO () -- -- echo sk = -- Stream.unfold Socket.readChunks sk -- SerialT IO (Array Word8) -- & Stream.fold (Socket.writeChunks sk) -- IO () -- @ -- -- = Programmer Notes -- -- Read IO requests to connected stream sockets are performed in chunks of -- 'Streamly.Internal.Data.Array.Foreign.Type.defaultChunkSize'. Unless -- specified otherwise in the API, writes are collected into chunks of -- 'Streamly.Internal.Data.Array.Foreign.Type.defaultChunkSize' before they are -- written to the socket. APIs are provided to control the chunking behavior. -- -- > import qualified Streamly.Network.Socket as Socket -- -- = See Also -- -- * "Streamly.Internal.Network.Socket" -- * <http://hackage.haskell.org/package/network network> ------------------------------------------------------------------------------- -- Internal Notes ------------------------------------------------------------------------------- -- -- A socket is a handle to a protocol endpoint. -- -- This module provides APIs to read and write streams and arrays from and to -- network sockets. Sockets may be connected or unconnected. Connected sockets -- can only send or recv data to/from the connected endpoint, therefore, APIs -- for connected sockets do not need to explicitly specify the remote endpoint. -- APIs for unconnected sockets need to explicitly specify the remote endpoint. -- -- By design, connected socket IO APIs are similar to -- "Streamly.Data.Array.Foreign" read write APIs. They are almost identical to the -- sequential streaming APIs in "Streamly.Internal.FileSystem.File". -- module Streamly.Network.Socket ( -- * Socket Specification SockSpec(..) -- * Accept Connections , accept -- * Read , read , readWithBufferOf , readChunks , readChunksWithBufferOf , readChunk -- * Write , write , writeWithBufferOf , writeChunks , writeChunksWithBufferOf , writeChunk -- * Exceptions , forSocketM ) where import Streamly.Internal.Network.Socket import Prelude hiding (read)