Skip to content

Commit 91cb58d

Browse files
committed
Merge PR #415
2 parents 15cd90b + bad026d commit 91cb58d

File tree

3 files changed

+58
-56
lines changed

3 files changed

+58
-56
lines changed

Network/Socket.hs

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -31,35 +31,35 @@
3131
-- > import Network.Socket.ByteString (recv, sendAll)
3232
-- >
3333
-- > main :: IO ()
34-
-- > main = withSocketsDo $ do
35-
-- > addr <- resolve "3000"
34+
-- > main = runTCPServer Nothing "3000" talk
35+
-- > where
36+
-- > talk s = do
37+
-- > msg <- recv s 1024
38+
-- > unless (S.null msg) $ do
39+
-- > sendAll s msg
40+
-- > talk s
41+
-- >
42+
-- > runTCPServer :: Maybe HostName -> ServiceName -> (Socket -> IO a) -> IO a
43+
-- > runTCPServer mhost port server = withSocketsDo $ do
44+
-- > addr <- resolve
3645
-- > E.bracket (open addr) close loop
3746
-- > where
38-
-- > resolve port = do
47+
-- > resolve = do
3948
-- > let hints = defaultHints {
4049
-- > addrFlags = [AI_PASSIVE]
4150
-- > , addrSocketType = Stream
4251
-- > }
43-
-- > addr:_ <- getAddrInfo (Just hints) Nothing (Just port)
44-
-- > return addr
52+
-- > head <$> getAddrInfo (Just hints) mhost (Just port)
4553
-- > open addr = do
4654
-- > sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)
4755
-- > setSocketOption sock ReuseAddr 1
48-
-- > -- If the prefork technique is not used,
49-
-- > -- set CloseOnExec for the security reasons.
5056
-- > withFdSocket sock $ setCloseOnExecIfNeeded
51-
-- > bind sock (addrAddress addr)
52-
-- > listen sock 10
57+
-- > bind sock $ addrAddress addr
58+
-- > listen sock 1024
5359
-- > return sock
5460
-- > loop sock = forever $ do
55-
-- > (conn, peer) <- accept sock
56-
-- > putStrLn $ "Connection from " ++ show peer
57-
-- > void $ forkFinally (talk conn) (\_ -> close conn)
58-
-- > talk conn = do
59-
-- > msg <- recv conn 1024
60-
-- > unless (S.null msg) $ do
61-
-- > sendAll conn msg
62-
-- > talk conn
61+
-- > (conn, _peer) <- accept sock
62+
-- > void $ forkFinally (server conn) (const $ gracefulClose conn 5000)
6363
--
6464
-- > {-# LANGUAGE OverloadedStrings #-}
6565
-- > -- Echo client program
@@ -71,23 +71,24 @@
7171
-- > import Network.Socket.ByteString (recv, sendAll)
7272
-- >
7373
-- > main :: IO ()
74-
-- > main = withSocketsDo $ do
75-
-- > addr <- resolve "127.0.0.1" "3000"
76-
-- > E.bracket (open addr) close talk
74+
-- > main = runTCPClient "127.0.0.1" "3000" $ \s -> do
75+
-- > sendAll s "Hello, world!"
76+
-- > msg <- recv s 1024
77+
-- > putStr "Received: "
78+
-- > C.putStrLn msg
79+
-- >
80+
-- > runTCPClient :: HostName -> ServiceName -> (Socket -> IO a) -> IO a
81+
-- > runTCPClient host port client = withSocketsDo $ do
82+
-- > addr <- resolve
83+
-- > E.bracket (open addr) close client
7784
-- > where
78-
-- > resolve host port = do
85+
-- > resolve = do
7986
-- > let hints = defaultHints { addrSocketType = Stream }
80-
-- > addr:_ <- getAddrInfo (Just hints) (Just host) (Just port)
81-
-- > return addr
87+
-- > head <$> getAddrInfo (Just hints) (Just host) (Just port)
8288
-- > open addr = do
8389
-- > sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)
8490
-- > connect sock $ addrAddress addr
8591
-- > return sock
86-
-- > talk sock = do
87-
-- > sendAll sock "Hello, world!"
88-
-- > msg <- recv sock 1024
89-
-- > putStr "Received: "
90-
-- > C.putStrLn msg
9192
--
9293
-- The proper programming model is that one 'Socket' is handled by
9394
-- a single thread. If multiple threads use one 'Socket' concurrently,

examples/EchoClient.hs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,21 @@ import Network.Socket
88
import Network.Socket.ByteString (recv, sendAll)
99

1010
main :: IO ()
11-
main = withSocketsDo $ do
12-
addr <- resolve "127.0.0.1" "3000"
13-
E.bracket (open addr) close talk
11+
main = runTCPClient "127.0.0.1" "3000" $ \s -> do
12+
sendAll s "Hello, world!"
13+
msg <- recv s 1024
14+
putStr "Received: "
15+
C.putStrLn msg
16+
17+
runTCPClient :: HostName -> ServiceName -> (Socket -> IO a) -> IO a
18+
runTCPClient host port client = withSocketsDo $ do
19+
addr <- resolve
20+
E.bracket (open addr) close client
1421
where
15-
resolve host port = do
22+
resolve = do
1623
let hints = defaultHints { addrSocketType = Stream }
17-
addr:_ <- getAddrInfo (Just hints) (Just host) (Just port)
18-
return addr
24+
head <$> getAddrInfo (Just hints) (Just host) (Just port)
1925
open addr = do
2026
sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)
2127
connect sock $ addrAddress addr
2228
return sock
23-
talk sock = do
24-
sendAll sock "Hello, world!"
25-
msg <- recv sock 1024
26-
putStr "Received: "
27-
C.putStrLn msg

examples/EchoServer.hs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,32 @@ import Network.Socket
99
import Network.Socket.ByteString (recv, sendAll)
1010

1111
main :: IO ()
12-
main = withSocketsDo $ do
13-
addr <- resolve "3000"
12+
main = runTCPServer Nothing "3000" talk
13+
where
14+
talk s = do
15+
msg <- recv s 1024
16+
unless (S.null msg) $ do
17+
sendAll s msg
18+
talk s
19+
20+
runTCPServer :: Maybe HostName -> ServiceName -> (Socket -> IO a) -> IO a
21+
runTCPServer mhost port server = withSocketsDo $ do
22+
addr <- resolve
1423
E.bracket (open addr) close loop
1524
where
16-
resolve port = do
25+
resolve = do
1726
let hints = defaultHints {
1827
addrFlags = [AI_PASSIVE]
1928
, addrSocketType = Stream
2029
}
21-
addr:_ <- getAddrInfo (Just hints) Nothing (Just port)
22-
return addr
30+
head <$> getAddrInfo (Just hints) mhost (Just port)
2331
open addr = do
2432
sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)
2533
setSocketOption sock ReuseAddr 1
26-
-- If the prefork technique is not used,
27-
-- set CloseOnExec for the security reasons.
2834
withFdSocket sock $ setCloseOnExecIfNeeded
29-
bind sock (addrAddress addr)
30-
listen sock 10
35+
bind sock $ addrAddress addr
36+
listen sock 1024
3137
return sock
3238
loop sock = forever $ do
33-
(conn, peer) <- accept sock
34-
putStrLn $ "Connection from " ++ show peer
35-
void $ forkFinally (talk conn) (\_ -> close conn)
36-
talk conn = do
37-
msg <- recv conn 1024
38-
unless (S.null msg) $ do
39-
sendAll conn msg
40-
talk conn
39+
(conn, _peer) <- accept sock
40+
void $ forkFinally (server conn) (const $ gracefulClose conn 5000)

0 commit comments

Comments
 (0)