@@ -11,20 +11,25 @@
12module Streamly.Internal.Network.Inet.TCP
12module Streamly.Internal.Network.Inet.TCP
15+ -- | To execute the code examples provided in this module in ghci, please
16+ -- run the following commands first.
14 -- * TCP Servers
20 -- * TCP Servers
15 -- ** Streams
21 -- ** Streams
16− acceptOnAddr
24+ , acceptOnAddr
17 , acceptOnAddrWith
25 , acceptOnAddrWith
19− -- , acceptOnPortWith
22 -- ** Unfolds
27 -- ** Unfolds
23 , acceptorOnAddr
31 , acceptorOnAddr
24 , acceptorOnAddrWith
32 , acceptorOnAddrWith
27− , acceptorOnPortLocal
29 -- * TCP clients
34 -- * TCP clients
30 -- | IP Address based operations.
35 -- | IP Address based operations.
@@ -89,6 +94,10 @@ module Streamly.Internal.Network.Inet.TCP
89 , datagrams
94 , datagrams
90 , datagramsOn
95 , datagramsOn
100+ , acceptorOnPortLocal
@@ -113,7 +122,7 @@ import Streamly.Data.Stream (Stream)
113import Streamly.Internal.Data.Tuple.Strict (Tuple'(..))
122import Streamly.Internal.Data.Tuple.Strict (Tuple'(..))
114import Streamly.Data.MutByteArray (Unbox)
123import Streamly.Data.MutByteArray (Unbox)
115import Streamly.Data.Unfold (Unfold)
124import Streamly.Data.Unfold (Unfold)
116−import Streamly.Internal.Network.Socket (SockSpec(..), accept, acceptor)
125+import Streamly.Internal.Network.Socket (SockSpec(..))
117import Streamly.Internal.System.IO (defaultChunkSize)
126import Streamly.Internal.System.IO (defaultChunkSize)
119import qualified Control.Monad.Catch as MC
128import qualified Control.Monad.Catch as MC
@@ -124,12 +133,17 @@ import qualified Streamly.Data.Fold as FL
124import qualified Streamly.Data.Stream as S
133import qualified Streamly.Data.Stream as S
125import qualified Streamly.Data.Unfold as UF
134import qualified Streamly.Data.Unfold as UF
126import qualified Streamly.Internal.Data.Array as A (pinnedChunksOf)
135import qualified Streamly.Internal.Data.Array as A (pinnedChunksOf)
127−import qualified Streamly.Internal.Data.Unfold as UF (first, bracketIO)
136+import qualified Streamly.Internal.Data.Unfold as UF (bracketIO)
128import qualified Streamly.Internal.Data.Fold as FL (Step(..), reduce)
137import qualified Streamly.Internal.Data.Fold as FL (Step(..), reduce)
130import qualified Streamly.Internal.Data.Stream.Exception.Lifted as S (bracket)
139import qualified Streamly.Internal.Data.Stream.Exception.Lifted as S (bracket)
131import qualified Streamly.Internal.Network.Socket as ISK
140import qualified Streamly.Internal.Network.Socket as ISK
132− (chunkReader, putBytes, putChunks, read, readChunks, writeChunks)
141+
145+-- >>> import qualified Streamly.Data.Unfold as Unfold
146+-- >>> import qualified Streamly.Network.Inet.TCP as TCP
134-------------------------------------------------------------------------------
148-------------------------------------------------------------------------------
135-- Accept (unfolds)
149-- Accept (unfolds)
@@ -140,7 +154,7 @@ acceptorOnAddrWith
140 :: MonadIO m
154 :: MonadIO m
141 => [(SocketOption, Int)]
155 => [(SocketOption, Int)]
142 -> Unfold m ((Word8, Word8, Word8, Word8), PortNumber) Socket
156 -> Unfold m ((Word8, Word8, Word8, Word8), PortNumber) Socket
143−acceptorOnAddrWith opts = UF.lmap f acceptor
157+acceptorOnAddrWith opts = UF.lmap f ISK.acceptor
145 f (addr, port) =
159 f (addr, port) =
146 (maxListenQueue
160 (maxListenQueue
@@ -163,36 +177,50 @@ acceptorOnAddr
163 => Unfold m ((Word8, Word8, Word8, Word8), PortNumber) Socket
177 => Unfold m ((Word8, Word8, Word8, Word8), PortNumber) Socket
164acceptorOnAddr = acceptorOnAddrWith []
178acceptorOnAddr = acceptorOnAddrWith []
166−{-# INLINE acceptorOnPortWith #-}
180+{-# INLINE acceptorWith #-}
167−acceptorOnPortWith :: MonadIO m
181+acceptorWith :: MonadIO m
168 => [(SocketOption, Int)]
182 => [(SocketOption, Int)]
169 -> Unfold m PortNumber Socket
183 -> Unfold m PortNumber Socket
170−acceptorOnPortWith opts = UF.first (0,0,0,0) (acceptorOnAddrWith opts)
184+acceptorWith opts = UF.first (0,0,0,0) (acceptorOnAddrWith opts)
172-- | Like 'acceptorOnAddr' but binds on the IPv4 address @0.0.0.0@ i.e. on all
186-- | Like 'acceptorOnAddr' but binds on the IPv4 address @0.0.0.0@ i.e. on all
173-- IPv4 addresses/interfaces of the machine and listens for TCP connections on
187-- IPv4 addresses/interfaces of the machine and listens for TCP connections on
174-- the specified port.
188-- the specified port.
176−-- > acceptorOnPort = UF.first acceptorOnAddr (0,0,0,0)
190+-- >>> acceptor = Unfold.first (0,0,0,0) TCP.acceptorOnAddr
192+{-# INLINE acceptor #-}
193+acceptor :: MonadIO m => Unfold m PortNumber Socket
194+acceptor = UF.first (0,0,0,0) acceptorOnAddr
196+{-# DEPRECATED acceptorOnPort "Use \"acceptor\" instead." #-}
178{-# INLINE acceptorOnPort #-}
197{-# INLINE acceptorOnPort #-}
179acceptorOnPort :: MonadIO m => Unfold m PortNumber Socket
198acceptorOnPort :: MonadIO m => Unfold m PortNumber Socket
180−acceptorOnPort = UF.first (0,0,0,0) acceptorOnAddr
199+acceptorOnPort = acceptor
182−-- | Like 'acceptorOnAddr' but binds on the localhost IPv4 address @127.0.0.1@.
201+-- | Like 'acceptor' but binds on the localhost IPv4 address @127.0.0.1@. The
183−-- The server can only be accessed from the local host, it cannot be accessed
202+-- server can only be accessed from the local host, it cannot be accessed from
184−-- from other hosts on the network.
203+-- other hosts on the network.
186−-- > acceptorOnPortLocal = UF.first acceptorOnAddr (127,0,0,1)
205+-- >>> acceptorLocal = Unfold.first (127,0,0,1) TCP.acceptorOnAddr
207+{-# INLINE acceptorLocal #-}
208+acceptorLocal :: MonadIO m => Unfold m PortNumber Socket
209+acceptorLocal = UF.first (127,0,0,1) acceptorOnAddr
211+{-# DEPRECATED acceptorOnPortLocal "Use \"acceptorLocal\" instead." #-}
188{-# INLINE acceptorOnPortLocal #-}
212{-# INLINE acceptorOnPortLocal #-}
189acceptorOnPortLocal :: MonadIO m => Unfold m PortNumber Socket
213acceptorOnPortLocal :: MonadIO m => Unfold m PortNumber Socket
190−acceptorOnPortLocal = UF.first (127,0,0,1) acceptorOnAddr
214+acceptorOnPortLocal = acceptorLocal
192-------------------------------------------------------------------------------
216-------------------------------------------------------------------------------
193-- Accept (streams)
217-- Accept (streams)
194-------------------------------------------------------------------------------
218-------------------------------------------------------------------------------
220+-- | Like 'acceptOnAddr' but with the ability to specify a list of socket
196{-# INLINE acceptOnAddrWith #-}
224{-# INLINE acceptOnAddrWith #-}
197acceptOnAddrWith
225acceptOnAddrWith
198 :: MonadIO m
226 :: MonadIO m
@@ -201,7 +229,7 @@ acceptOnAddrWith
201 -> PortNumber
229 -> PortNumber
202 -> Stream m Socket
230 -> Stream m Socket
203acceptOnAddrWith opts addr port =
231acceptOnAddrWith opts addr port =
204− accept maxListenQueue SockSpec
232+ ISK.accept maxListenQueue SockSpec
205 { sockFamily = AF_INET
233 { sockFamily = AF_INET
206 , sockType = Stream
234 , sockType = Stream
207 , sockProto = defaultProtocol
235 , sockProto = defaultProtocol
@@ -209,8 +237,9 @@ acceptOnAddrWith opts addr port =
210 (SockAddrInet port (tupleToHostAddress addr))
238 (SockAddrInet port (tupleToHostAddress addr))
212−-- | Like 'accept' but binds on the specified IPv4 address of the machine
240+-- | Like 'accept' but binds on the specified IPv4 address.
213−-- and listens for TCP connections on the specified port.
241+--
242+-- >>> acceptOnAddr = TCP.acceptOnAddrWith []
215-- /Pre-release/
244-- /Pre-release/
216{-# INLINE acceptOnAddr #-}
245{-# INLINE acceptOnAddr #-}
@@ -221,27 +250,27 @@ acceptOnAddr
221 -> Stream m Socket
250 -> Stream m Socket
222acceptOnAddr = acceptOnAddrWith []
251acceptOnAddr = acceptOnAddrWith []
224−-- | Like 'accept' but binds on the IPv4 address @0.0.0.0@ i.e. on all
253+-- | Start a TCP stream server that binds on the IPV4 address @0.0.0.0@ and
225−-- IPv4 addresses/interfaces of the machine and listens for TCP connections on
254+-- listens for TCP connections from remote hosts on the specified server port.
226−-- the specified port.
255+-- The server generates a stream of connected sockets.
228−-- > acceptOnPort = acceptOnAddr (0,0,0,0)
257+-- >>> accept = TCP.acceptOnAddr (0,0,0,0)
230-- /Pre-release/
259-- /Pre-release/
231−{-# INLINE acceptOnPort #-}
260+{-# INLINE accept #-}
232−acceptOnPort :: MonadIO m => PortNumber -> Stream m Socket
261+accept :: MonadIO m => PortNumber -> Stream m Socket
233−acceptOnPort = acceptOnAddr (0,0,0,0)
262+accept = acceptOnAddr (0,0,0,0)
235-- | Like 'accept' but binds on the localhost IPv4 address @127.0.0.1@.
264-- | Like 'accept' but binds on the localhost IPv4 address @127.0.0.1@.
236-- The server can only be accessed from the local host, it cannot be accessed
265-- The server can only be accessed from the local host, it cannot be accessed
237-- from other hosts on the network.
266-- from other hosts on the network.
239−-- > acceptOnPortLocal = acceptOnAddr (127,0,0,1)
268+-- >>> acceptLocal = TCP.acceptOnAddr (127,0,0,1)
241-- /Pre-release/
270-- /Pre-release/
242−{-# INLINE acceptOnPortLocal #-}
271+{-# INLINE acceptLocal #-}
243−acceptOnPortLocal :: MonadIO m => PortNumber -> Stream m Socket
272+acceptLocal :: MonadIO m => PortNumber -> Stream m Socket
244−acceptOnPortLocal = acceptOnAddr (127,0,0,1)
273+acceptLocal = acceptOnAddr (127,0,0,1)
246-------------------------------------------------------------------------------
275-------------------------------------------------------------------------------
247-- TCP Clients
276-- TCP Clients