Haskell で ソケットを使ったクライアント-サーバ通信をやってみる。
Haskell を使ったネットワーク・プログラミングの入り口が分かればいいので、クライアントから受け取った文字列をひっくり返して返すだけの、簡単なお題とする。
まず、サーバはこんな感じ。import Network
import System.IO
main :: IO ()
main = withSocketsDo $ do
hSetBuffering stdout NoBuffering
server `catch` (const $ putStrLn "Exception caught.")
putStrLn "Connection closed."
server :: IO ()
server = do
sock <- listenOn (PortNumber 8001)
repeats (receive sock)
sClose sock
repeats :: Monad m => m Bool -> m ()
repeats x =
x >>= (\x' -> if x' then (return ()) else repeats x)
receive :: Socket -> IO Bool
receive sock = do
(h,host,port) <- accept sock
hSetBuffering h LineBuffering
msg <- hGetLine h
putStrLn msg
hPutStrLn h $ reverse msg
return $ null msg
クライアントはこんな感じ。
import Network
import System.IO
sendMessage msg = withSocketsDo $ do
hSetBuffering stdout NoBuffering
h <- connectTo "127.0.0.1" (PortNumber 8001)
hSetBuffering h LineBuffering
hPutStrLn h msg
hGetLine h >>= putStrLn
hClose h
実行は GHCi でやってみる。以下、サーバ側
ghci> :load server.hs [1 of 1] Compiling Main ( server.hs, interpreted ) Ok, modules loaded: Main. ghci> main Loading package bytestring-0.9.1.10 ... linking ... done. ・・・略・・・ Loading package network-2.3.0.7 ... linking ... done. hello 1234 Connection closed. ghci>以下、クライアント側
ghci> :load client.hs [1 of 1] Compiling Main ( client.hs, interpreted ) Ok, modules loaded: Main. ghci> sendMessage "hello" Loading package bytestring-0.9.1.10 ... linking ... done. ・・・略・・・ Loading package network-2.3.0.7 ... linking ... done. olleh ghci> sendMessage "1234" 4321 ghci> sendMessage "" ghci>
思ったより難しくない。次は、マルチスレッド化かなあ。
0 件のコメント:
コメントを投稿