« Erlang の smart_exception で例外が変になる | Main | Erlang Tips 更新 »

Friday, June 15, 2007

Erlang で echo server

gen_tcp の練習で echo server 書いてみたより


誰か添削してくれないかなぁ…

ということなので,わたしならこう書く,というものを以下に.
添削というほどのことは無理ですが,自分の練習を兼ねて…(^^;

-module(echoserver2). -export([start/0, handle_connection/1, recv_loop/1]).

start() ->
  {ok, ListenSocket} = gen_tcp:listen(8080,
    [{active, false}, binary, {packet, line}, {reuseaddr, true}]),
  accept(ListenSocket).

accept(ListenSocket) ->
  {ok, Socket} = gen_tcp:accept(ListenSocket),
  spawn(?MODULE, handle_connection, [Socket]),
  accept(ListenSocket).

handle_connection(Socket) ->
  gen_tcp:send(Socket, <<"hello\r\n">>),
  recv_loop(Socket).

recv_loop(Socket) ->
  case gen_tcp:recv(Socket, 0) of
    {ok, B} ->
      case B of
        <<"bye\r\n">> ->
          gen_tcp:send(Socket, <<"cya\r\n">>),
          gen_tcp:close(Socket);
        Other ->
          gen_tcp:send(Socket, Other),
          recv_loop(Socket)
      end;
    {error, closed} ->
      ok
  end.


※見た目のために全角スペース入り.

以下修正点など.

・そもそもの仕様がよくわからないのだけど,echoサーバなら,1行入れるたびに応答が返ってくるもの,という想定にした.
 元のコードでは,手元の環境では何も入力せずに改行をした場合に,それまでの応答が返ってきていた.
 また,byeを入れても終了しなかった.
 (たぶんパケットの切れ目が環境によって異なるためと思う)

・listen では,reuseaddr しておいた方が何かと良いと思うので,追加.
 reuseaddr していないと,一度止めて再度起動したときに,ポートが使用中で listen に失敗することがある.

・1行単位での入出力さえあれば十分と思うので,listen には {packet, line} オプションを渡した.
 これで,入力は1行単位になるので,recv_loop の受信処理でパケット境界を気にしなくて済む.
 ※ただし,1行が長すぎると途中で切れるので,その点では注意が必要

・spawnするときのモジュール名は ?MODULE マクロを使うように.
 後でモジュールの名前を変える時に余計な手間を省くことが出来る.

|

« Erlang の smart_exception で例外が変になる | Main | Erlang Tips 更新 »

Comments

態々ありがとうございます!
とても勉強になります m(_ _)m

Posted by: cooldaemon | Saturday, June 16, 2007 at 09:07 PM

Post a comment



(Not displayed with comment.)


Comments are moderated, and will not appear on this weblog until the author has approved them.



TrackBack

TrackBack URL for this entry:
http://app.cocolog-nifty.com/t/trackback/33589/15446690

Listed below are links to weblogs that reference Erlang で echo server:

» [erlang]proc_lib で echoserver を書き直した [cooldaemonの備忘録]
gen_server、supervisor、proc_lib の三つを押さえれば、httpd.erl の起動と停止の動作を理解する事が可能。 って事で、以前 みかログ: Erlang で echo server こちらで添削して頂いた id:cooldaemon:20070614 を proc_lib で書き直してみた。 -module(echoserver3). -expor... [Read More]

Tracked on Tuesday, July 17, 2007 at 09:46 PM

» telnet接続で計算問題を出題する [fujishinko 雑記帳]
telnetで繋ぐと計算問題が出題・それに回答する。 http://mymo.blog8.fc2.com/blog-entry-35.html これをErlangでやってみました。 %% -*- coding: utf-8 -*- -module(sample). -export([start/0, handle_connection/1, recv_loop/2]). start() - {ok, Lis... [Read More]

Tracked on Sunday, January 24, 2010 at 12:34 AM

« Erlang の smart_exception で例外が変になる | Main | Erlang Tips 更新 »