2014-03-26 63 views
2

考慮一個簡單的回聲服務器的以下的erlang代碼:二郎:至controlling_process(),或不controlling_process()

回聲聽者:

-module(echo_listener). 
-export([start_link/1]). 

-define(TCP_OPTIONS, [binary, {packet, 0}, {reuseaddr, true}, 
         {keepalive, true}, {backlog, 30}, {active, false}]). 

start_link(ListenPort) -> 
    {ok, ListenSocket} = gen_tcp:listen(ListenPort, ?TCP_OPTIONS), 
    accept_loop(ListenSocket). 

accept_loop(ListenSocket) -> 
    {ok, ClientSocket} = gen_tcp:accept(ListenSocket), 
    Pid = spawn(echo_worker, usher, [ClientSocket]), 
    gen_tcp:controlling_process(ClientSocket, Pid), 
    accept_loop(ListenSocket). 

回聲工人:

-module(echo_worker). 
-export([echo/1]). 

echo(ClientSocket) -> 
    case gen_tcp:recv(ClientSocket, 0) of 
     {ok, Data} -> 
      gen_tcp:send(ClientSocket, Data), 
      echo(ClientSocket); 
     {error, closed} -> 
      ok 
    end. 

無論何時接受客戶端套接字,echo服務器都會生成一個echo工作者,並將該客戶端套接字直接作爲函數參數傳遞。在代碼中有controller_process(),但我已經嘗試了代碼而不調用controls_process(),它也可以。

controls_process()的真正目的是什麼?何時需要?

在此先感謝。

回答

2

Erlang的文件說,有關調用gen_tcp:controlling_process/1:

分配一個新的控制進程的PID到插座。控制過程是從套接字接收消息的過程。如果 被當前控制進程以外的任何其他進程調用,則返回 {error,not_owner}。

您創建聽與選項{活躍,假}插座,你調用gen_tcp同步讀取插座:RECV/2,因此你的代碼仍然工作,而無需調用調用gen_tcp的:controlling_process/1。但是,如果要異步接收數據,則必須使用選項{active,true}創建偵聽套接字。在這種情況下,接受連接的所有者將收到有關傳入數據的消息。所以如果你不調用gen_tcp:controls_process/1,這些消息將被髮送到監聽器進程而不是worker。