2011-08-14 5 views
3

誰でも、実行時に次のエラーが表示される理由を説明できますか:erl -noshell -s simple_server、次にtelnet 127.0.0.1 1084?コード自体はエラーメッセージの下にあります。ヘルプエラーレポートの理解

=エラーレポート==== 13日 - 8月2011 :: 23:12: {{エラーBadMatch、{誤差、閉じ:プロセス< 0.30.0 05 ===エラー> 終了値を持ちます}}、[{simple_server、wait_accept、1}]}

-module(simple_server). 
    -compile(export_all). 

    start() -> 
     {ok, ListenSoc} = gen_tcp:listen(1084, [binary, {active, false}]), 
     wait_accept(ListenSoc). 

    wait_accept(ListenSoc) -> 
     {ok, Socket} = gen_tcp:accept(ListenSoc), 
     spawn(?MODULE, wait_accept, [ListenSoc]), 
     send_resp(Socket). 

    send_resp(Socket) -> 
     gen_tcp:send(Socket, "Response from simple server...\n"), 
     ok = gen_tcp:close(Socket). 

答えて

4

この事:

{{badmatch,{error,closed}}, 
[{simple_server,wait_accept,1}]} 

のように読まれるべきである。そして、私たちが得た: "wait_accept/1我々はsimple_serverです"バッドマッチエラー(http://www.erlang.org/doc/reference_manual/errors.html#id81191参照)。これは、(それはそれは簡単です、その関数内のみ一致式のように)私たちの一致式

{ok, Socket} = gen_tcp:accept(ListenSock), 

{error, closed}を返したことを意味します。なぜそれが戻ってきたのか、私は少しばかげている。最善の策は、start/0関数を呼び出すプロセスが終了し、その終了のために待機ソケットが閉じられていることです(これは自動的に行われます)。 erlangシェルのエラーがそれを再起動するので、リスンソケットを閉じます。

3

ソケットが作成されると、ソケット制御プロセスと呼ばれる現在のプロセスにリンクされます。制御プロセスが終了すると、リンクされたソケットはすべて閉じられます。あなたの場合ListenSocは、send_resp()が終了しているので(ソケットの制御プロセスが終了した)、新しく作成されたプロセスのgen_tcp:accept(ListenSoc){error, closed}を返したときに閉じられます。

最も簡単な修正では、このようwait_acceptgen_tcp:contorolling_process/2への呼び出しを追加することです:

... 
Pid = spawn(?MODULE, wait_accept, [ListenSoc]), 
ok = gen_tcp:controlling_process(ListenSoc, Pid), 
... 

しかし、本当のプロジェクトでは、待機ソケット制御処理でループする方が良いでしょう。あなたは答えをNicolas Buduroiから得ることができます。

+0

本当に適切であるためには、ソケットなしでプロセスを生成し、 'controlled_process/2'を呼び出して、ソケット内のプロセスにメッセージを送ります。これは、まだ所有していないソケットからプロセスを読み取ることができないようにするためです。 –