1、主动消息获取(非阻塞)

第一个例子是以主动模式打开socket,然后接受来自socket的数据:

{ok,Listen} = gen_tcp:listen(Port,[...,{active,true}...]),

{ok,Socket} = gen_tcp:accept(Listen), loop(Socket).

loop(Socket) ->

receive

{tcp,Socket,Data} -> ... 输出处理 ...

{tcp_closed,Socket} -> ...

end.

这个过程无法控制发到服务器循环的消息流,如果客户端产生数据的速度大于服务器消费数据的速度,系统就会收到洪水般地消息-消息缓冲区溢出,系统将会crash并表现怪异。

这种类型的服务器叫做非阻塞服务器,因为它无法阻塞客户端。我们仅在信任客户端的情况下才会使用非阻塞服务器。

2 被动消息获取(阻塞)

在这一节,我们写阻塞服务器:服务器以被动模式打开socket,通过 {active,false} 选项。这个服务器不会被危险的客户端洪水袭击。

服务器循环中的代码调用 gen_tcp:recv 来接收数据。客户端在服务器调用 recv 之前会被阻塞。注意OS会对客户端发来的数据做一下缓冲,以允许客户端在服务器调用 recv 之前仍然可以继续发送一小段数据。

{ok,Listen} = gen_tcp:listen(Port,[...,{active,false}...]),

{ok,Socket} = gen_tcp:accept(Listen), loop(Socket).

loop(Socket) ->

case gen_tcp:recv(Socket,N) of {ok,B} -> ... 数据处理 ... loop(Socket);

{error,closed} ...

end.

3 混合消息获取(部分阻塞)

你可能认为把被动模式用到所有服务器上都合适。不幸的是,当我们在被动模式时,我们只能等待来自于一个socket的数据。这对于需要等待多个socket来源数据的服务器则不适用。

幸运的是我们可以用混合方式,既不是阻塞的也不是非阻塞的。我们以一次主动(active once)模式 {active,once} 打开socket。在这个模式中,socket是主动的,但是只能接收一条消息。在控制进程发出一条消息之后,他必须明确的调用 inet:setopts 以便让socket恢复并接收下一条消息。系统在这发生之前会一直阻塞。这是两种世界的最好结合点。如下是代码:

{ok,Listen} = gen_tcp:listen(Port,[...,{active,once}...]),

{ok,Socket} = gen_tcp:accept(Listen), loop(Socket).

loop(Socket) ->

receive

{tcp,Socket,Data} -> ... 数据处理 ... %%准备好启用下一条消息时

inet:setopts(Socket,[{active,once}]),

loop(Socket);

{tcp_closed,Socket} -> ...

end.

使用 {active,once} 选项,用户可以实现高层次的数据流控制(有时叫交通管制),同时又防止了服务器被过多的消息洪水所淹没。

inet:sockname(Socket) 返回本地地址和端口号 {ok, {Address, Port}}
inet:peername(Socket) 返回连接的另一端 地址和端口 {ok, {Address, Port}}
inet:setopts(Sock, [{active, once}]),我们可以让数据乖乖的听话,主动发给我们一个数据,然后变不主动,我们处理完这个消息后,然后在设置active once,其继续再发给我们一个数据. 这样的好处是,不会因为{active, true},给我们发送了大量的数据,导致我们应接不暇.也不会让我们每次都手动 gen_tcp:recv/2数据,那么累人

eclipse erlang插件已经修改为: 
http://download.erlide.org/update

转载于:https://www.cnblogs.com/huangliang-hb/p/8489865.html

erlang之三种socket消息循环相关推荐

  1. android 结束if循环_Android Handler 消息循环机制

    前言 一问起Android应用程序的入口,很多人会说是Activity中的onCreate方法,也有人说是ActivityThread中的静态main方法.因为Java虚拟机在运行的时候会自动加载指定 ...

  2. android 消息循环机制--looper handler

    Looper类说明   Looper 类用来为一个线程跑一个消息循环. 线程在默认情况下是没有消息循环与之关联的,Thread类在run()方法中的内容执行完之后就退出了,即线程做完自己的工作之后就结 ...

  3. TApplication与主消息循环

    Windows应用程序的每一个窗口都有一个大的消息循环以及一个窗口函数(WndProc)用以分发和处理消息.VCL作为一个Framework,当然会将这些东西隐藏起来,而重新提供一种易用的.易理解的虚 ...

  4. 2.创建适合游戏的窗口和消息循环

    2.创建适合游戏的窗口和消息循环 本章前言: 创建游戏窗口和处理消息循环是很重要的事情,我尝试过几种不同的窗口处理方式,这次打算使用WS_POPUP样式的窗口(无边框).上一次的框架代码把创建窗口和消 ...

  5. 1.4 消息循环和回调函数

    ************************************************** * 本文由小鸟飞飞整理发表 <samboy@sohu.com> * * 首发网站:蓝丽 ...

  6. 模态对话框的消息循环原理及分析笔记

    简述: APP消息循环和模态对话框中局部消息循环的关系 根据上图可以看出,在APP的消息循环再派发ONOK消息后,调用ModalDlg的响应函数,pWnd->OnOk();在该消息中, 会 进入 ...

  7. 模态对话框和非模态对话框的消息循环分析

    1.非模态对话框和父窗口共享当前线程的消息循环 2.模态对话框新建一个新的消息循环,并由当前消息循环派发消息,而父窗口.模态对话框屏蔽了用户对它父窗口的操作,但是不是在消息循环里面屏蔽,所以给父窗口发 ...

  8. 深入理解MFC消息循环和消息泵的原理

    首先,应该清楚MFC的消息循环(::GetMessage,::PeekMessage),消息泵(CWinThread::PumpMessage)和MFC的消息在窗口之间的路由是两件不同的事情.在MFC ...

  9. 详谈Windows消息循环机制

    一直对windows消息循环不太清楚,今天做个详细的总结,有说错的地方,请务必指出. 用VS2017新建一个win32 Application的默认代码如下: 这里有几个概念,容易混淆: 1.系统: ...

最新文章

  1. 5、删除被其它表关联的主表
  2. 1.2.1 计算机硬件的基本组成
  3. Git出现Unable to create 'E:/xxx/.git/index.lock': File exists.的解决办法
  4. 实战 | 尝鲜 Svelte 前端框架,开发读书笔记
  5. 资中筠 - 百度百科
  6. vue-calendar 基于 vue 2.0 开发的轻量,高性能日历组件
  7. 微型计算机音乐发生器,基于51单片机的音乐发生器的设计最终版(全文完整版)...
  8. centos7设置键盘类型_CentOS7设置中文输入法
  9. linux 图片转视频教程,如何在Ubuntu上转换图像、音频和视频格式
  10. 医院信息化集成平台建设
  11. vue报错:vue.js:634 [Vue warn]: Cannot find element: #app
  12. C++ 第一阶段编程练习
  13. Android 常用正则表达式,android编程实战
  14. 自我管理的29个工具
  15. CD光盘中CDA格式转音频文件
  16. 企企通:数字化浪潮下,企业如何利用间接采购策略,实现降本增效?
  17. 304413存储过程和触发器
  18. win10没有7zip的右键菜单
  19. 数据分析(一)百度指数,代码如下:
  20. Windows权限提升

热门文章

  1. Python Cookbook(第3版)pdf
  2. How to setup a DL4J project with eclipse
  3. 开源Math.NET基础数学类库使用(03)C#解析Matlab的mat格式
  4. linux之git入门命令
  5. Java中J.U.C扩展组件之ForkJoinTask和ForkJoinPool
  6. JVM,JRE,JDK之间的区别和联系
  7. ubuntu16 下 源码配置Lnmp环境
  8. ubuntu proxy
  9. c语言蓝色字体,C 语言输出不同颜色字体
  10. 网络多人游戏架构pdf_21秒看尽ImageNet屠榜模型,60+模型架构同台献艺