erlang R17带来了新的socket选项{active,N} 。与{active,once}连同应用层提供的流量控制。为什么会这样选择,{active,once}不能够有效地抑制了很多socket消息做?

我们知道,,{active,once}一次设置active选项,才干继续接收erlang的消息通知。实际上。每次设定{active,once}都意味着调用一次epoll_ctl, 假设请求过于频繁,就会有大量的epoll_ctl调用。erlang眼下仅仅有一个线程会收割epoll_wait事件。epoll_wait要轮询已经就绪的ctl队列。假设大量的ctl事件将会堵塞了epoll_wait的操作,造成网络处理能力的下降。

那么。我们能不能设定接收N个的socket消息后再运行一次epoll_ctl。这样能够有效降低epoll_ctl的调用。{active,N}就是这样出现的。

以下来看一下{active,N}的说明

Add the {active,N} socket option for TCP, UDP, and SCTP,where N is an integer in the range -32768..32767, to allow a caller to specify the number of data messages to be delivered to the controlling process. Once the
socket's delivered message count either reaches 0 or is explicitly set to 0 with inet:setopts/2 or by including {active,0} as an option when the socket is created, the socket transitions to passive({active, false}) mode and the socket's controlling process receives
a message to inform it of the transition. TCP sockets receive {tcp_passive,Socket}, UDP sockets receive {udp_passive,Socket} and SCTP sockets receive {sctp_passive,Socket}. 



The socket's delivered message counter defaults to 0, but it can be set using {active,N} via any gen_tcp, gen_udp, or gen_sctp function that takes socket options as arguments, or via inet:setopts/2. New N values are added to the socket's current counter value,
and negative numbers can be used to reduce the counter value. Specifying a number that would cause the socket's counter value to go above 32767 causes an einval error. If a negative number is specified such that the counter value would become negative, the
socket's counter value is set to 0 and the socket transitions to passive mode. If the counter value is already 0 and inet:setopts(Socket, [{active,0}]) is specified, the counter value remains at 0 but the appropriate passive mode transition message is generated
for the socket.

设定了{active,N}选项后,进程在接收了N个包后,会收到{tcp_passive, Socket}消息,意味着这个Socket进入被动模式,须要又一次设置active选项。

接下来。在实际的样例中測试这个參数:

-module(server).

-export([start/0]).
-export([continue/1]).
-define( PORT, 8888). start() ->
{ok, LSock} = gen_tcp:listen(?PORT, [binary, {packet, 0},{active, false}]),
io:format("socket listen: ~p on ~p ~n",[LSock, ? PORT]),
accept(LSock). accept(LSock) ->
{ok, ASock} = gen_tcp:accept(LSock),
Pid = spawn(fun() -> do_loop(ASock) end),
gen_tcp:controlling_process(ASock, Pid),
inet:setopts(ASock, [{active, 3}]),
accept(LSock). do_loop(ASock) ->
receive
{tcp, Socket, Data} ->
io:format("socket ~p recv: ~p ~n",[Socket, Data]);
{tcp_closed, Socket} ->
io:format("socket ~p close ~n",[Socket]);
{tcp_passive,Socket} ->
io:format("socket ~p is passive, please call continue/1 ~p ~n",[Socket, self()]);
release_passive ->
inet:setopts(ASock, [{active, 3}]);
Err ->
io:format("socket may error: ~p ~n",[Err])
end,
do_loop(ASock). continue(Pid) ->
Pid ! release_passive,
ok.

编译启动这个模块后。我们创建一个client来请求这个服务端:

1> f(S), {ok,S} = gen_tcp:connect({127,0,0,1},8888,[{packet,0}]).
{ok,#Port<0.526>}
2> gen_tcp:send(S,<<"hello">>).
ok
3> gen_tcp:send(S,<<"hello">>).
ok
4> gen_tcp:send(S,<<"hello">>).
ok
5> gen_tcp:send(S,<<"hello">>).
ok

服务端控制台打印了这种信息:

D:\tmp>erl -s server
socket listen: #Port<0.422> on 8888
Eshell V6.0 (abort with ^G)
1> socket #Port<0.479> recv: <<"hello">>
1> socket #Port<0.479> recv: <<"hello">>
1> socket #Port<0.479> recv: <<"hello">>
1> socket #Port<0.479> is passive, please call continue/1 <0.33.0>
1> server:continue(pid(0,33,0)).
socket #Port<0.479> recv: <<"hello">>
ok
2>

在上面的样例中,我们设定了{active,3}的选项,在接收到client3次数据后,socket进入了passive状态,在又一次设置{active,N}后继续接收tcp消息。

那么,怎样在实际项目中运用{active,N}选项?

inet:setopts(Socket, [{active, 300}]),
erlang:send_after(30 * 1000, self(), release_passive);

大概思路是,在30秒内最多接收300个包。超过就不接收,等待这30秒完毕后继续接收。如此重复。

利用这点还能够加多一个计数器,假设超过10次进入passive状态,说明这个Socket存在问题,有攻击的行为。

參考:

http://blog.csdn.net/mycwq/article/details/24814843

http://www.erlang.org/download/otp_src_17.0.readme

http://blog.yufeng.info/archives/2970

erlang R17新socket选项{active,N}的更多相关文章

  1. 解决erlang R17无法识别中文问题

    erlang更新到R17已有一段时间了.公司项目打算从旧版的erlang迁移到R17,却不料有不少的困扰,当中一个问题是中文问题. 这个问题非常easy重现:新建一个文件t.erl.保存为utf-8无 ...

  2. 浅谈Linux环境下Socket选项的设置

    0.前言 TCP/IP协议栈是Linux内核的重要组成部分和网络编程的基石,虽然Linux和BSD有很大的联系,但是对于某些Socket选项和内核操作仍然存在差异,因此文中适用场景均为CentOS环境 ...

  3. 提高服务端性能的几个socket选项

    提高服务端性能的几个socket选项 在之前的一篇文章中,作者在配置了SO_REUSEPORT选项之后,使得应用的性能提高了数十倍.现在介绍socket选项中如下几个可以提升服务端性能的选项: SO_ ...

  4. Socket编程基础——Socket选项

    有些情况下,我们需要对Socket行为和属性进一步控制,例如修改缓冲区大小,查看Socket状态,这就需要设置/获取Socket选项. 1.获取Socket选项int getsockopt(SOCKE ...

  5. 《用Java写一个通用的服务器程序》03 处理新socket

    在讲监听器时说过处理的新的socket要尽快返回,监听器调用的是ClientFactory的createPhysicalConnection方法,那么就来看这个方法: public boolean c ...

  6. Linux 高性能服务器编程——socket选项

    socket选项函数 功能:用来读取和设置socket文件描述符属性的方法 函数: #include <sys/scoket.h> int getsockopt ( int sockfd, ...

  7. 常用socket选项

    1.socket选项通常:服务端应在listen 前设置,accpet返回的socket继承自监听套接字. 客户端应在connect之前设置 2.socket 如果有大量短连接应设置SO_LINGER ...

  8. Socket编程中的强制关闭与优雅关闭及相关socket选项

    以下描述主要是针对windows平台下的TCP socket而言. 首先需要区分一下关闭socket和关闭TCP连接的区别,关闭TCP连接是指TCP协议层的东西,就是两个TCP端之间交换了一些协议包( ...

  9. socket选项总结(setsocketopt)

    功能描述:        获取或者设置与某个套接字关联的选 项.选项可能存在于多层协议中,它们总会出现在最上面的套接字层.当操作套接字选项时,选项位于的层和选项的名称必须给出.为了操作套接字层的选项, ...

随机推荐

  1. Nginx——事件驱动机制(雷霆追风问题,负载均衡)

    事件处理框架 所有的worker进程都在ngx_worker_process_cycle方法中循环处理事件,处理分发事件则在ngx_worker_process_cycle方法中调用ngx_proce ...

  2. android学习经常使用的数据文件夹

    android工程实践 1.仿360一键清理实现(一) "一键清理"是一个桌面图标,点击图标后,显示一个视图.进行清理动画.之后显示清理了几个进程,释放了多少M内存.点击" ...

  3. MSSQL只能访问特定的数据库

    让用户只能访问特定的数据库(MSSQL) 背景 客户的SQL Server实例上有多个厂商的数据库,每个数据库由各自的进行厂进行商维护, 为了限定不同厂商的维护人员只能访问自己的数据库,现需要给各个厂 ...

  4. OTN&互换amp; P-OTN有效降低100G 网络成本 (两)

    OTN互换& P-OTN有效降低100G 网络成本 (两) 在全球范围内.网流量的增长速度是空前的,导致此现象的缘由包含云服务的增长.移动宽带和基于互联网的视频点播服务的增长. Cisco估计 ...

  5. [Unity3D]脚本中Start()和Awake()的差别

    Unity3D刚開始学习的人常常把Awake和Start混淆. 简单说明一下,Awake在MonoBehavior创建后就立马调用,Start将在MonoBehavior创建后在该帧Update之前. ...

  6. PHP关联数组和哈希表(hash table) 未指定

    PHP有数据的一个非常重要的一类,就是关联数组.又称为哈希表(hash table),是一种很好用的数据结构. 在程序中.我们可能会遇到须要消重的问题,举一个最简单的模型: 有一份username列表 ...

  7. WebAPI 15 CORS

    WebAPI 15 CORS 同源策略 首先基于安全的原因,浏览器是存在同源策略这个机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. 对于同源必须要求URL在如下几个方 ...

  8. BZOJ3362 [Usaco2004 Feb]Navigation Nightmare 导航噩梦

    标题效果:自脑补. 思维:与维护两个维度和可设置为检查右. 注意,标题给予一堆关系的.我们应该加入两对关系. Code: #include <cstdio> #include <cs ...

  9. 《Tips for Optimizing C/C++ Code》译文

    前不久在微博上看到一篇非常好的短文讲怎样对C/C++进行性能优化,尽管其面向的领域是图形学中的光线跟踪,可是还是具有普遍的意义,将其翻译成中文,希望对大家写高质量代码有帮助. 1.     牢记阿姆达 ...

  10. C++中的class (2)

    class Father { protected void methodA(){ //do something } private void methodB(){//do something } } ...