关于gen_tcp:controlling_process函数的使用
December 13th, 2008 :: Godwit
初学Erlang,碰到一个小小的问题,拿出来跟大家分享一下。:)
想用gen_server写一个简单的客户端,要求可以无阻塞的接收。开始想的很简单,关键代码如下。
- start( Host, Port ) ->
- io:format( “Client is starting…~n” ),
- gen_server:start_link( {local, ?MODULE}, ?MODULE, [Host, Port], [] ).
- init( [Host, Port] ) ->
- { ok, Socket } = gen_tcp:connect( Host, Port,
- [ binary, { packet, 4 }, { active, true } ] ),
- Pid = spawn( fun() -> sendRecvMsg( Socket ) end ),
- %%该处加入gen_tcp:controlling_process( Socket, Pid ),
- Data = #data{ socket = Pid },
- { ok, Data }.
- sendRecvMsg( Socket ) ->
- receive
- { tcp, Socket, Bin } ->
- %% 注意:此处收不到消息
- sendRecvMsg( Socket );
- { send, Message } ->
- gen_tcp:send( Socket, Message ),
- %% 注意:此处可以收到消息,但是显然是阻塞接收的。
- receive
- { tcp, Socket, Bin } ->
- io:format( “Receive something!~n”)
- after 1000 ->
- sendRecvMsg( Socket)
- end
- end.
想了好多方法,没有解决,回头认真的把书相关章节读了读,顿悟(参见《Erlang程序设计》第196页):
创建一个套接字的进程(通过调用gen_tcp:accept或gen_tcp:connect)也就是所说的该套接字的控制进程。这个套接字所收到的任何消息都会转发给这个控制进程,如果控制进程消亡,那么该套接字也会自行关闭。我们可以通过gen_tcp:controlling_process(Socket, NewPid)函数来把一个套接字的控制进程改为新的控制进程NewPid。
所以,在spawn之后加入如下语句:
gen_tcp:controlling_process( Socket, Pid ),
就可以了。
代码能否好好排一下, 看起来太乱!!!
@sw2wolf
稍微改了下,希望看起来可以舒服些。
Wordpress的缩进功能我掌握的不好。。。
一行一行的改太浪费时间了。。。
@Godwit,代码排版,可以参看顶部菜单中的“使用帮助?”。
不错