gen_tcp の練習で echo server 書いてみた
-module(echoserver). -export([start/0, handle_connection/1, recv_loop/2]). start() -> {ok, ListenSocket} = gen_tcp:listen(8080, [{active, false}, binary]), io:fwrite("listen~n"), accept(ListenSocket). accept(ListenSocket) -> {ok, Socket} = gen_tcp:accept(ListenSocket), io:fwrite("accept~n"), Pid = spawn(echoserver, handle_connection, [Socket]), io:fwrite("spawn ~w~n", [Pid]), accept(ListenSocket). handle_connection(Socket) -> gen_tcp:send(Socket, "hello\r\n"), recv_loop(Socket, []). recv_loop(Socket, Bs) -> case gen_tcp:recv(Socket, 0) of {ok, B} -> case B of <<"\r\n">> -> case list_to_binary(Bs) of <<"bye">> -> gen_tcp:send(Socket, "cya\r\n"), gen_tcp:close(Socket), io:fwrite("bye~n"); Other -> gen_tcp:send(Socket, Other), gen_tcp:send(Socket, "\r\n"), io:fwrite("send~n"), recv_loop(Socket, []) end; _ -> io:fwrite("B :~p~n", [B]), io:fwrite("Bs:~s~n", [Bs]), recv_loop(Socket, [Bs, B]) end; {error, closed} -> io:fwrite("close~n") end.
誰か添削してくれないかなぁ…
添削してもらえた!
大感謝!本当にありがとうございます!
みかログ: Erlang で echo server
仕様は、下記を考えておりました。
- 8080 で listen
- accept 後は、プロセスを分ける事で、client からの接続を複数受け付ける
- CRLF が入力されるまで入力を受け付ける
- CRLF が入力されると、それまで入力された文字列を echo する
- bye が入力されると切断される
添削結果を拝見させて頂いて、次回以降、気をつけようと思った箇所のまとめ
- gen_tcp:listen のオプションに {reuseaddr, true} を指定する事
- gen_tcp:listen のオプションには、{packet, line} もあって便利(一行が長すぎると切れる場合もある ←要調査)
gen_tcp:listen のオプションに binary を指定した場合は、gen_tcp:send の第二引数に binary を設定する事- 文字列より binary の方が小メモリで扱う場合に高速である為、binary を優先的に使う事
- ?MODULE マクロで、モジュール名が取得できる(spawn や gen_server:call とかで使う)
プロセスの終了時に ok を返しておく
早く仕事に使えるくらい精通したい