on 5d096df help sign in
155 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 non-streaming 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 'accept' stream to start listening for
19-- connections from clients. 'accept' 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.Prelude as Stream
37-- >>> import qualified Streamly.Network.Socket as Socket
38-- >>>
39-- >>> :{
40-- main :: IO ()
41-- main = do
42-- let spec = SockSpec
43-- { sockFamily = AF_INET
44-- , sockType = Stream
45-- , sockProto = defaultProtocol
46-- , sockOpts = []
47-- }
48-- addr = SockAddrInet 8090 (tupleToHostAddress (0,0,0,0))
49-- in server spec addr
50-- where
51-- server spec addr =
52-- Socket.accept maxListenQueue spec addr
53-- & Stream.parMapM (Stream.eager True) (Socket.forSocketM echo)
54-- & Stream.fold Fold.drain
55-- echo sk =
56-- Socket.readChunks sk -- Stream IO (Array Word8)
57-- & Stream.fold (Socket.writeChunks sk) -- IO ()
58-- :}
59--
60-- = Programmer Notes
61--
62-- Read IO requests to connected stream sockets are performed in chunks of
63-- 'Streamly.Internal.Data.Array.Type.defaultChunkSize'. Unless
64-- specified otherwise in the API, writes are collected into chunks of
65-- 'Streamly.Internal.System.IO.defaultChunkSize' before they are written to
66-- the socket.
67--
68-- >>> import qualified Streamly.Network.Socket as Socket
69--
70-- = See Also
71--
72-- * "Streamly.Internal.Network.Socket"
73-- * <http://hackage.haskell.org/package/network network>
75-------------------------------------------------------------------------------
76-- Internal Notes
77-------------------------------------------------------------------------------
78--
79-- A socket is a handle to a protocol endpoint.
80--
81-- This module provides APIs to read and write streams and arrays from and to
82-- network sockets. Sockets may be connected or unconnected. Connected sockets
83-- can only send or recv data to/from the connected endpoint, therefore, APIs
84-- for connected sockets do not need to explicitly specify the remote endpoint.
85-- APIs for unconnected sockets need to explicitly specify the remote endpoint.
86--
87-- By design, connected socket IO APIs are similar to
88-- "Streamly.Data.Array.Foreign" read write APIs. They are almost identical to the
89-- sequential streaming APIs in "Streamly.Internal.FileSystem.File".
90--
91module Streamly.Network.Socket
92 (
93 -- * Socket Specification
94 SockSpec(..)
96 -- * Accept Connections
97 , accept
98 , acceptor
100 -- * Reads
101 -- ** Singleton
102 , getChunk
104 -- ** Streams
105 , read
106 , readWith
107 , readChunks
108 , readChunksWith
110 -- ** Unfolds
111 , reader
112 , readerWith
113 , chunkReader
114 , chunkReaderWith
116 -- * Writes
117 -- ** Singleton
118 , putChunk
120 -- ** Folds
121 , write
122 , writeWith
123 , writeChunks
124 , writeChunksWith
126 -- * Exceptions
127 , forSocketM
129 -- * Deprecated
130 , readChunk
131 , writeChunk
132 , readWithBufferOf
133 , readChunksWithBufferOf
134 , writeWithBufferOf
135 , writeChunksWithBufferOf
136 )
137where
139import Data.Word (Word8)
140import Network.Socket (Socket)
141import Streamly.Data.Array (Array)
142import Streamly.Data.MutByteArray (Unbox)
144import Streamly.Internal.Network.Socket
145import Prelude hiding (read)
147{-# DEPRECATED readChunk "Please use 'getChunk' instead" #-}
148{-# INLINABLE readChunk #-}
149readChunk :: Int -> Socket -> IO (Array Word8)
150readChunk = getChunk
152{-# DEPRECATED writeChunk "Please use 'putChunk' instead" #-}
153{-# INLINABLE writeChunk #-}
154writeChunk :: Unbox a => Socket -> Array a -> IO ()
155writeChunk = putChunk