Old/sampou.org/Programming_Network
Programming_Network
Programming:Network
とりあえずの Echo サーバ
\begin{code}
module Main where
import Control.Concurrent
import Network
import System.IO
type Service = String -> String
port :: PortNumber
port = 8888
echo :: Service
echo = id
main :: IO ()
main = server port echo
server :: PortNumber -> Service -> IO ()
server p sc = withSocketsDo $ listenOn (PortNumber p) >>= serve sc
serve :: Service -> Socket -> IO ()
serve sc sock = accept sock >>= forkIO . service sc >> serve sc sock
service :: Service -> (Handle, HostName, PortNumber) -> IO ()
service sc (h,_,_) = hSetBuffering h LineBuffering >> loop h sc
loop :: Handle -> Service -> IO ()
loop h sc = hIfEOF h (return ()) $ hGetLine h >>= hPutStrLn h . sc >> loop h sc
hIfEOF :: Handle -> IO a -> IO a -> IO a
hIfEOF h t e = hIsEOF h >>= \ eof -> if eof then t else e
\end{code}
とりあえずのEchoサーバ(低レベルAPI, 非関数プログラミング志向, 最低仕様)
私の環境では上記のHigh Level API利用だとservname no supportedになる。 アドレス解決ができない模様なのでLow Level APIを叩いてみた。cut-sea:2008/06/05 05:24:09 JST
- クライアント側でのアドレス指定をFQDNじゃなくて、IPアドレス(127.0.0.1)でやってもアクセスできませんか? MacOSでもはこれで上手くいった。Ubuntu 8.04 では問題なし。
- あークライアント以前に上記サーバが起動に失敗するのでつ。cut-sea:2008/06/05 11:47:28 JST
これかも GHC ticket#2103 iquiw:2008/06/11 14:10:52 JST
- 低レベルAPI : 低レイヤのNetworkライブラリ(Network.Socket)を利用した。
- 非関数プログラミング志向 : 関数プログラミング志向で書けなかっただけ。
最低仕様 : 複数接続やら切断など一切処理してない最低限のecho。終了にはserverをCtrl-Cなどで殺す。
import Network.Socket
server sv = do s0 <- sock0
bindSocket s0 addr0
listen s0 5
(s1,a1) <- accept s0
sv s1
where
sock0 = socket AF_INET Stream 0
addr0 = SockAddrInet 8888 0x0100007f -- 127.0.0.1:8888
echo s = do (rcv, len, addr) <- recvFrom s 2048
send s rcv
echo s
main :: IO a
main = server echo
なぜかIP Addressの指定が1.0.0.127的にしないと127.0.0.1にならない。
もしかしてBig/Little Endianがおかしい?(pkgsrcからbuildしたghcなんだけど)
正直流れが見えるまで、何故こんなAPIになってるのかムカついてたんだけど…
ステップバイステップでないと書けない子なので、
sock0 = socket AF_INET Stream 0
addr0 = SockAddrInet 8888 0x0100007f -- 127.0.0.1:8888
:
:
みたいな調子でロードしてはsock0やらaddr0やら確認してた。 するとbindとlistenのところでハマって、 ようやくsocketの返すのがIO Socketという風にIOモナドに包まれている理由が分った。 なーる。
Last modified : 2008/06/11 14:10:52 JST