[color=red][b]一、erlang socket的消息流的三种控制方式:[/b][/color]
1 主动模式 {active, true}
2 被动模式 {active, false}
3 混合模式 {active, once}
[color=blue][b]1 主动消息获取(非阻塞)[/b][/color]
在该模式下,无法控制发到服务端的消息流,如果客户端生产消息的速度大于服务端消费消息的速度,会导致服务端消息缓冲区溢出
[color=blue][b]2 被动消息获取(阻塞)[/b][/color]
被动模式下,每收到一条信息,进行阻塞,防止危险客户端消息洪水的袭击
服务器调用gen_tcp:recv来接收数据,客户端在服务端调用recv前被阻塞
[color=blue][b]3 混合模式(半阻塞)[/b][/color]
服务器以一次主动模式{active,once}接收且仅能接收一条消息,在接收消息后,必须明确调用inet:setopts恢复socket来接收下一条消息。系统在这发生前,一直处于阻塞状态
[b][color=red]二、socket的控制进程[/color][/b]
创建socket的进程(调用gen_tcp:accept或gen_tcp:connect)叫做这个socket的控制进程,所有来自socket的消息都会被发送到控制进程,如果控制进程死掉,对应的socket会被关闭,
可以通过gen_tcp:controlling_process(Socket, Pid)来修改socket的控制进程。
1 主动模式 {active, true}
2 被动模式 {active, false}
3 混合模式 {active, once}
[color=blue][b]1 主动消息获取(非阻塞)[/b][/color]
在该模式下,无法控制发到服务端的消息流,如果客户端生产消息的速度大于服务端消费消息的速度,会导致服务端消息缓冲区溢出
{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.
[color=blue][b]2 被动消息获取(阻塞)[/b][/color]
被动模式下,每收到一条信息,进行阻塞,防止危险客户端消息洪水的袭击
{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前被阻塞
[color=blue][b]3 混合模式(半阻塞)[/b][/color]
服务器以一次主动模式{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.
[b][color=red]二、socket的控制进程[/color][/b]
创建socket的进程(调用gen_tcp:accept或gen_tcp:connect)叫做这个socket的控制进程,所有来自socket的消息都会被发送到控制进程,如果控制进程死掉,对应的socket会被关闭,
可以通过gen_tcp:controlling_process(Socket, Pid)来修改socket的控制进程。