on ec2856c help sign in
156 lines 4.9 kB history raw
1-- |
2-- Module : Streamly.Network.Socket
3-- Copyright : (c) 2018 Composewell Technologies
4--
5-- License : BSD-3-Clause
6-- Maintainer : streamly@composewell.com
7-- Stability : released
8-- Portability : GHC
9--
10-- This module provides socket based streaming APIs to to receive connections
11-- from remote hosts, and to read and write from and to network sockets.
12--
13-- For basic socket types and operations please consult the @Network.Socket@
14-- module of the <http://hackage.haskell.org/package/network network> package.
15--
16-- = Examples
17--
18-- To write a server, use the 'acceptor' unfold to start listening for
19-- connections from clients. 'acceptor' generates a stream of connected
20-- sockets. We can map an effectful action on this socket stream to handle the
21-- connections. The action would typically use socket reading and writing
22-- operations to communicate with the remote host. We can read/write a stream
23-- of bytes or a stream of chunks of bytes ('Array').
24--
25-- Following is a short example of a concurrent echo server. Please note that
26-- this example can be written even more succinctly by using higher level
27-- operations from "Streamly.Network.Inet.TCP" module.
28--
29-- >>> :set -XFlexibleContexts
30-- >>>
31-- >>> import Data.Function ((&))
32-- >>> import Network.Socket
33-- >>> import Streamly.Network.Socket (SockSpec(..))
34-- >>>
35-- >>> import qualified Streamly.Data.Fold as Fold
36-- >>> import qualified Streamly.Data.Stream as Stream
37-- >>> import qualified Streamly.Data.Stream.Prelude as Stream
38-- >>> import qualified Streamly.Network.Socket as Socket
39-- >>>
40-- >>> :{
41-- main :: IO ()
42-- main = do
43-- let spec = SockSpec
44-- { sockFamily = AF_INET
45-- , sockType = Stream
46-- , sockProto = defaultProtocol
47-- , sockOpts = []
48-- }
49-- addr = SockAddrInet 8090 (tupleToHostAddress (0,0,0,0))
50-- in server spec addr
51-- where
52-- server spec addr =
53-- Socket.accept maxListenQueue spec addr
54-- & Stream.parMapM (Stream.eager True) (Socket.forSocketM echo)
55-- & Stream.fold Fold.drain
56-- echo sk =
57-- Socket.readChunks sk -- Stream IO (Array Word8)
58-- & Stream.fold (Socket.writeChunks sk) -- IO ()
59-- :}
60--
61-- = Programmer Notes
62--
63-- Read IO requests to connected stream sockets are performed in chunks of
64-- 'Streamly.Internal.Data.Array.Type.defaultChunkSize'. Unless
65-- specified otherwise in the API, writes are collected into chunks of
66-- 'Streamly.Internal.System.IO.defaultChunkSize' before they are written to
67-- the socket.
68--
69-- >>> import qualified Streamly.Network.Socket as Socket
70--
71-- = See Also
72--
73-- * "Streamly.Internal.Network.Socket"
74-- * <http://hackage.haskell.org/package/network network>
76-------------------------------------------------------------------------------
77-- Internal Notes
78-------------------------------------------------------------------------------
79--
80-- A socket is a handle to a protocol endpoint.
81--
82-- This module provides APIs to read and write streams and arrays from and to
83-- network sockets. Sockets may be connected or unconnected. Connected sockets
84-- can only send or recv data to/from the connected endpoint, therefore, APIs
85-- for connected sockets do not need to explicitly specify the remote endpoint.
86-- APIs for unconnected sockets need to explicitly specify the remote endpoint.
87--
88-- By design, connected socket IO APIs are similar to
89-- "Streamly.Data.Array.Foreign" read write APIs. They are almost identical to the
90-- sequential streaming APIs in "Streamly.Internal.FileSystem.File".
91--
92module Streamly.Network.Socket
93 (
94 -- * Socket Specification
95 SockSpec(..)
97 -- * Accept Connections
98 , accept
99 , acceptor
101 -- * Reads
102 -- ** Singleton
103 , getChunk
105 -- ** Streams
106 , read
107 , readWith
108 , readChunks
109 , readChunksWith
111 -- ** Unfolds
112 , reader
113 , readerWith
114 , chunkReader
115 , chunkReaderWith
117 -- * Writes
118 -- ** Singleton
119 , putChunk
121 -- ** Folds
122 , write
123 , writeWith
124 , writeChunks
125 , writeChunksWith
127 -- * Exceptions
128 , forSocketM
130 -- * Deprecated
131 , readChunk
132 , writeChunk
133 , readWithBufferOf
134 , readChunksWithBufferOf
135 , writeWithBufferOf
136 , writeChunksWithBufferOf
137 )
138where
140import Data.Word (Word8)
141import Network.Socket (Socket)
142import Streamly.Data.Array (Array)
143import Streamly.Data.MutByteArray (Unbox)
145import Streamly.Internal.Network.Socket
146import Prelude hiding (read)
148{-# DEPRECATED readChunk "Please use 'getChunk' instead" #-}
149{-# INLINABLE readChunk #-}
150readChunk :: Int -> Socket -> IO (Array Word8)
151readChunk = getChunk
153{-# DEPRECATED writeChunk "Please use 'putChunk' instead" #-}
154{-# INLINABLE writeChunk #-}
155writeChunk :: Unbox a => Socket -> Array a -> IO ()
156writeChunk = putChunk