2012年2月26日日曜日

Erlang timer server

下記URLにあるタイマーサーバを真似てみた。
Erlang Programming Language : http://www.erlang.org/article/15

サーバと通信するクライアントも作った。

サーバは現在日付と時刻を返す。
クライアントはそれを表示する。

ただひとつ問題があった。Vistaだからかもしれないが、gen_tcp:recv()でパケットを受信しようとすると、エラールートに入ってしまう。いろいろ調べてみたけど、よくわからなかった。Winsock が原因じゃないかと思うけど。

◆サーバ

-module(time_srv).
-compile(export_all).

%%start( Pno ) ->
%%    spawn( ?MODULE, loop0, [ Pno ] ).
start() ->
    %%spawn( ?MODULE, loop0, [ 12346 ] ).
    loop0( 12346 ).

loop0( Port ) ->
    case gen_tcp:listen( Port, [ binary, { packet, 0 }, { active, false } ] ) of
        { ok, LSock } ->
            io:format("listen success~n"),
            loop( LSock );
        _ ->
            io:format("listen failed~n"),
            stop
   
    end.

loop( Listen ) ->
    io:format("loop start.~n"),
    case gen_tcp:accept( Listen ) of
        { ok, S } ->
            io:format("accept success~n"),
            gen_tcp:send( S, io_lib:format( "~p~n", [ { date(), time() } ] ) ),
            io:format("send success~n"),
            gen_tcp:close( S ),
            loop( Listen );
        _ ->
            io:format("accept failed~n"),
            loop( Listen )
    end.


◆クライアント
-module( time_cli ).
-compile( export_all ).

client() ->
    %% サーバ接続先
    Server = "localhost",
    %% サーバに接続
    { ok, Sock } = gen_tcp:connect( Server,
                                    12346,
                                    [ binary, { packet, 0} ] ),
    %% サーバからデータ受信
    do_recv( Sock ),
    %% ソケットの終了
    gen_tcp:close( Sock ).

do_recv( Sock ) ->
    receive
        { tcp, Sock, Pct } ->
             io:format( "time:~p~n", [ Pct ] );
        _ -> io:format( "error" )
    end.