`

Erlang--TCP学习(五)总结篇

阅读更多
一、erlang socket的消息流的三种控制方式:
  1 主动模式 {active, true}
  2 被动模式 {active, false}
  3 混合模式 {active, once}

1 主动消息获取(非阻塞)
  在该模式下,无法控制发到服务端的消息流,如果客户端生产消息的速度大于服务端消费消息的速度,会导致服务端消息缓冲区溢出
{ok, ListenSocket} = gen_tcp:listen(Port, [...,{active,true}...],
{ok, Socket} = gen_tcp:accept(ListenSocket}
loop_receive(Socket).

loop_receive(Socket) ->
    receive
        {tcp, Socket, Bin} ->
            ...
            loop_receive(Socket);
        {tcp_closed, Socket} ->
            ...
    end. 


2 被动消息获取(阻塞)
  被动模式下,每收到一条信息,进行阻塞,防止危险客户端消息洪水的袭击
{ok, ListenSocket} = gen_tcp:listen(Port, [...,{active,false}...],
{ok, Socket} = gen_tcp:accept(ListenSocket}
loop_receive(Socket).

loop_receive(Socket) ->
    case gen_tcp:recv(Socket, N) of
        {ok, Packet} ->
            ...
            loop_receive(Socket);
        {error, reason} ->
            ...
    end. 

  服务器调用gen_tcp:recv来接收数据,客户端在服务端调用recv前被阻塞

3 混合模式(半阻塞)
  服务器以一次主动模式{active,once}接收且仅能接收一条消息,在接收消息后,必须明确调用inet:setopts恢复socket来接收下一条消息。系统在这发生前,一直处于阻塞状态
{ok, ListenSocket} = gen_tcp:listen(Port, [...,{active,once}...],
{ok, Socket} = gen_tcp:accept(ListenSocket}
loop_receive(Socket).

loop_receive(Socket) ->
    receive
        {tcp, Socket, Bin} ->
            ...
            inet:setopts(Socket,[{active,once}]),
            loop_receive(Socket);
        {tcp_closed, Socket} ->
            ...
    end. 


二、socket的控制进程
  创建socket的进程(调用gen_tcp:accept或gen_tcp:connect)叫做这个socket的控制进程,所有来自socket的消息都会被发送到控制进程,如果控制进程死掉,对应的socket会被关闭,
可以通过gen_tcp:controlling_process(Socket, Pid)来修改socket的控制进程。


 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics