1{-# LANGUAGE CPP, BangPatterns #-}
8import qualified Data.Serialize as Ser
9import Data.Word (Word8)
11 ( AddrInfoFlag (AI_PASSIVE), HostName, ServiceName, Socket
12 , SocketType (Stream), SocketOption (ReuseAddr)
13 , accept, addrAddress, addrFlags, addrFamily, bindSocket, defaultProtocol
15 , getAddrInfo, listen, setSocketOption, socket, sClose, withSocketsDo )
16import System.Environment (getArgs, withArgs)
17import Data.Time (getCurrentTime, diffUTCTime, NominalDiffTime)
18import System.IO (withFile, IOMode(..), hPutStrLn, Handle, stderr)
19import Control.Concurrent (forkIO)
20import Control.Concurrent.MVar (newEmptyMVar, takeMVar, putMVar)
21import qualified Network.Socket as N
23import Data.ByteString (ByteString)
24import Data.ByteString.Char8 (pack, unpack)
25import qualified Data.ByteString as BS
26import qualified Network.Socket.ByteString as NBS
27import Data.Time (getCurrentTime, diffUTCTime, NominalDiffTime)
32 serverReady <- newEmptyMVar
36 putStrLn "server: creating TCP connection"
37 serverAddrs <- getAddrInfo
38 (Just (defaultHints { addrFlags = [AI_PASSIVE] } ))
41 let serverAddr = head serverAddrs
42 sock <- socket (addrFamily serverAddr) Stream defaultProtocol
43 setSocketOption sock ReuseAddr 1
44 bindSocket sock (addrAddress serverAddr)
46 putStrLn "server: awaiting client connection"
47 putMVar serverReady ()
49 (clientSock, clientAddr) <- accept sock
51 putStrLn "server: listening for pings"
56 let pings = read pingsStr
57 serverAddrs <- getAddrInfo
61 let serverAddr = head serverAddrs
62 sock <- socket (addrFamily serverAddr) Stream defaultProtocol
64 N.connect sock (addrAddress serverAddr)
68pingMessage :: ByteString
69pingMessage = pack "ping123"
71ping :: Socket -> Int -> IO ()
72ping sock pings = go pings
76 putStrLn $ "client did " ++ show pings ++ " pings"
78 before <- getCurrentTime
81 after <- getCurrentTime
82 -- putStrLn $ "client received " ++ unpack bs
83 let latency = (1e6 :: Double) * realToFrac (diffUTCTime after before)
84 hPutStrLn stderr $ show i ++ " " ++ show latency
87pong :: Socket -> IO ()
90 -- putStrLn $ "server received " ++ unpack bs
91 when (BS.length bs > 0) $ do
95-- | Wrapper around NBS.recv (for profiling)
96recv :: Socket -> Int -> IO ByteString
98 (header, payload) <- BS.splitAt 4 `fmap` NBS.recv sock (4 + i)
99 case Ser.decode header :: Either String Int32 of
100 Left _ -> error "Could not decode header"
101 Right _ -> return payload
105header = Ser.encode (8 :: Int32)
107-- | Wrapper around NBS.send (for profiling)
108send :: Socket -> ByteString -> IO ()
110 NBS.sendMany sock [header, bs]
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list