haskellでなんかつくる。

ここまでやったんだし、なんか作ってみることもできそうだなと思った。ためしにクライアントの送信してきた内容をそのまま標準出力に流すだけのサーバを書いてみました。

import Network
import System.IO

main = withSocketsDo $ do
    socket <- listenOn $ PortNumber 9999
    (handle, hostname, port) <- accept socket
    cs <- hGetContents handle
    putStr cs

ライブラリのマニュアル読みつつ適当に。withSocketDoはWindowsじゃなかったらいらないらしい。

C:\hoge\docs\hs>ghc -Lc:/ghc/ghc-6.8.2/lib/network-2.1.0.0 -lHSnetwork-2.1.0.0 server.hs -o server

コンパイル。できた! 実は一番時間かかったのは、コンパイルするところ。

動かしてみる

C:\hoge\docs\hs>server

だんまり。そりゃ接続無けりゃ何も言わんわな。telnetで接続してやります。(なんかVistaの中にtelnetが見あたらんかったので、VMWare内のLinuxから)

% telnet 192.168.117.1 9999
Trying 192.168.117.1...
Connected to 192.168.117.1.
Escape character is '^]'.
hoge
hogehoge
C:\hoge\docs\hs>server
hoge
hogehoge

ネットワーク越しにデータやりとりできました。すごいな!

そういえばなんか、closeとかしてないなたぶん。

import Network
import System.IO

main = withSocketsDo $ do
    socket <- listenOn $ PortNumber 9999
    (handle, hostname, port) <- accept socket
    cs <- hGetContents handle
    putStr cs
    hClose handle
    sClose socket
C:\hoge\docs\hs>ghc -Lc:/ghc/ghc-6.8.2/lib/network-2.1.0.0 -lHSnetwork-2.1.0.0 server.hs -o server

こうか。


あと考えてみりゃ、telnetが無いとか言う前に自分でクライアンも書けばいいんだよな。

import Network
import System.IO

main = withSocketsDo $ do
    handle <- connectTo "127.0.0.1" $ PortNumber 9999
    cs <- getContents
    hPutStr handle cs
    hClose handle

じゃあこのクライアントと先のサーバで通信テスト。

C:\hoge\docs\hs>ghc -Lc:/ghc/ghc-6.8.2/lib/network-2.1.0.0 -lHSnetwork-2.1.0.0 client.hs -o client

C:\hoge\docs\hs>client
hoge
fuga
piyo
^Z

以下はサーバ側の出力。

C:\hoge\docs\hs>server
hoge
fuga
piyo

なんだか結構楽に書けた気がしますね。

GHCはマニュアルがけっこういいですね。型とかだけしか書いてなかったりする部分もありますけど。でも型だけ書いてあっても、型がちゃんと分けられてるので、だいたい「ああこのデータコンストラクタで作った値をこっちに渡してやんのかなー」とか想像しやすい気がしました。

test