- 浏览: 129607 次
- 性别:
- 来自: 杭州
最新评论
-
zhi_nan_7:
做一个软件,需求是这样的:银行软件,需要对(excel)表格 ...
如何应对表结构经常变化? -
GuolinLee:
{A, _int, [B|_int], {B}} = {abc ...
erlang 中带下划线变量的使用 -
mozhenghua:
兄弟有没有啥解决方案呀?
MVC中被忽略的View层 -
ccchenzhong:
仁兄,还有哪边有你的这篇文章可看。如果有,可以给我个链接?或是 ...
javarebel 原理分析--说明 -
lingqi1818:
一晃一年过去了。。。
回顾2010,展望2011
Day 11 Programming with Sockets
• gen_tcp 和 gen_udp 两个包
使用TCP
• 从服务器取数据
• 1. {ok,Socket}=gen_tcp:connect(Host,Port,Params)
• 2. ok = gen_tcp:send(Socket,Data).
• 3.receive_data,处理两种包{tcp,Socket,Bin}和{tcp_closed,Socket}
receive_data(Socket, SoFar) ->
receive
{tcp,Socket,Bin} ->
receive_data(Socket, [Bin|SoFar]); %% 注意,这里list里的数据的顺序是倒的,最后要lists:reverse一下
{tcp_closed,Socket} ->
list_to_binary(reverse(SoFar))
end.
• 一个简单的TCP Server
start_nano_server() ->
{ok, Listen} = gen_tcp:listen(2345, [binary, {packet, 4},
{reuseaddr, true},
{active, true}]),
{ok, Socket} = gen_tcp:accept(Listen),
gen_tcp:close(Listen),
loop(Socket).
• 这个server很简单,监听端口,接受一次请求,然后处理那个请求
• {ok,Listen}=gen_tcp:listen(Port,Params).
• {ok,Socket}=gen_tcp:accept(Listen).
• 然后这个Socket就一样的处理了
• 改进一下,可以处理多次请求,只是简单的在处理完请求之后继续接收新的连接
start_seq_server() ->
{ok, Listen} = gen_tcp:listen(...),
seq_loop(Listen).
seq_loop(Listen) ->
{ok, Socket} = gen_tcp:accept(Listen),
loop(Socket),
seq_loop(Listen).
• 其他的改进,可以同时处理多个请求,接收连接之后,但前进程处理请求,新开一个进程去等待连接
start_parallel_server() ->
{ok, Listen} = gen_tcp:listen(...),
spawn(fun() -> par_connect(Listen) end).
par_connect(Listen) ->
{ok, Socket} = gen_tcp:accept(Listen),
spawn(fun() -> par_connect(Listen) end),
loop(Socket).
• 打开Socket的进程被称为控制进程,socket收到的消息都会发给控制进程,如果控制进程死掉了,那这个socket也会被关掉,可以通过gen_tcp:controlling_process(Socket, NewPid).来修改一个socket的控制进程
• 上面的并发处理的server有一个问题,有可能打开无数个处理进程,解决办法就是可以加个计数器
• 接收一个请求,创建socket之后,最好是明确的设定这个socket的一些参数,例如
{ok, Socket} = gen_tcp:accept(Listen),
inet:setopts(Socket, [{packet,4},binary,
{nodelay,true},{active, true}]),
loop(Socket)
• R11B-3 版本之后,erlang允许多个进程同时监听同一个Listen的socket,这样就可以实现创建一个pool来处理连接了
Control Issues
• erlang 的socket可以以三种模式打开active,active once,passive,可以在gen_tcp:listen,或者gen_tcp:connect的时候设置参数 {active, true | false | once}
• active socket,当数据来的时候,控制进程会收到{tcp, Socket, Data}消息,控制进程无法控制什么时候收到这些消息,完全被动的,nonblocking
• passive socket,控制进程必须使用gen_tcp:recv(Socket, N)明确的指定从Socket中读取N个字节,(如果N为0的话,所有可用的数据都会读出来),读取的时候是需要等待的,这样,服务器就可以完全控制什么时候读取数据,blocking
Active Message Reception (Nonblocking)
{ok, Listen} = gen_tcp:listen(Port, [..,{active, true}...]),
{ok, Socket} = gen_tcp:accept(Listen),
loop(Socket).
loop(Socket) ->
receive
{tcp, Socket, Data} ->
... do something with the data ...
{tcp_closed, Socket} ->
...
end.
• 如果客户端不停的发送消息,同时服务端处理的速度跟不上的话,服务器端将会被撑死,这就是flood攻击
• 因为服务器端无法block住客户端,因此称之为nonblocking server
• 只有在确信能支撑起客户端的需要的时候才使用这种方式
Passive Message Reception (Blocking)
{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} ->
... do something with the data ...
loop(Socket);
{error, closed}
...
end.
• 服务器端可以自由的控制在需要的时候才调用recv,因此在此之前客户端将被block住(操作系统的buffer除外)
• 因此服务器端很安全,至少程序不至于被客户端疯狂的发信息而撑死(操作系统撑死除外)
• 这种阻塞模式服务器也只能等待一个socket的数据
The Hybrid Approach (Partial Blocking)
{ok, Listen} = gen_tcp:listen(Port, [..,{active, once}...]),
{ok, Socket} = gen_tcp:accept(Listen),
loop(Socket).
loop(Socket) ->
receive
{tcp, Socket, Data} ->
... do something with the data ...
%% when you're ready enable the next message
inet:setopts(Sock, [{active, once}]),
loop(Socket);
{tcp_closed, Socket} ->
...
end.
• 我们使用{active,once},这样收到消息之后,socket变成passive模式,等我们处理完消息之后,再设置socket为{active,once}
• 这样,服务端不会被客户端的数据撑死了,同时也能处理很多连接的请求了
• @spec inet:peername(Socket) -> {ok, {IP_Address, Port}} | {error, Why}
• 可以查看Socket的另一边是谁
• IP_Address的格式{N1,N2,N3,N4},{K1,K2,K3...K8}分别支持IPV4,IPV6,这里的N和K都是0-255的整数
Socket编程的错误处理
• 不需要错误处理!
• 如果控制进程死掉了,相应的socket就会断开,另一端会收到消息{tcp_closed,Socket}
UDP
• UDP因为是无连接的协议,因此编程模型很简单,最简单的服务器
server(Port) ->
{ok, Socket} = gen_udp:open(Port, [binary]),
loop(Socket).
loop(Socket) ->
receive
{udp, Socket, Host, Port, Bin} ->
BinReply = ... ,
gen_udp:send(Socket, Host, Port, BinReply),
loop(Socket)
end.
• 客户端也很简单
client(Request) ->
{ok, Socket} = gen_udp:open(0, [binary]),
ok = gen_udp:send(Socket, "localhost" , 4000, Request),
Value = receive
{udp, Socket, _, _, Bin} ->
{ok, Bin}
after 2000 ->
error
end,
gen_udp:close(Socket),
Value.
Additional Notes on UDP
• 由于UDP是无连接的,因此有可能同一个包会发送两次,这时就分不清楚到底有没有接收到过这个包了
• 要解决的话,可以在请求的包里加上一个唯一标志,然后让服务端也返回这个标志,这样,接收的时候就可以检查是不是相应的回答了,不过如果那种没有回答的请求呢?
• 可以使用make_ref()来获得一个erlang系统内唯一的标志
Broadcasting to Multiple Machines
-module(broadcast).
-compile(export_all).
send(IoList) ->
case inet:ifget("eth0" , [broadaddr]) of
{ok, [{broadaddr, Ip}]} ->
{ok, S} = gen_udp:open(5010, [{broadcast, true}]),
gen_udp:send(S, Ip, 6000, IoList),
gen_udp:close(S);
_ ->
io:format("Bad interface name, or\n"
"broadcasting not supported\n" )
end.
listen() ->
{ok, S} = gen_udp:open(6000),
loop(S).
loop(S) ->
receive
Any ->
io:format("received:~p~n" , [Any]),
loop(S)
end.
• 注意广播需要网络支持
• 一般的路由器会屏蔽跨子网的udp广播包
TODO 阅读SHOUTcast server代码
发表评论
-
读了一下hotwheels的代码
2009-08-31 11:56 2561上次提到的一个挑战, ... -
不错的erlang tutorial
2009-08-19 09:41 1213http://learnyousomeerlang.com/ ... -
erlang 新书 "OTP and Erlang in Action"
2009-08-17 17:40 1374一本新书,似乎还未完成,见 http://pokingarou ... -
erlang.org似乎挂了
2009-08-17 11:38 1230从昨天起,erlang.org就无法访问了,ping能ping ... -
为啥我的erlide超慢无比?
2009-08-06 16:08 1378为啥我的erlide超慢无比? 刚下载的一个eclip ... -
erlang 程序性能优化挑战
2009-07-20 12:03 1965OpenPoker 的作者Joel Reymont 发起的 ... -
erlang programming 比programming erlang这本书好
2009-07-15 16:38 1913这两本书我都是看英文pdf的,看了TheBook之后,没啥感觉 ... -
erlang中的message发送的几个事实
2009-07-13 17:59 1836这个世界是并行的,我们每个人都有自己的思想,你没法知道我想什么 ... -
在ubuntu上编译erlang with wx
2009-07-12 09:10 1968因为ubuntu维护的erlang版本太旧,因此从某时开始,我 ... -
并不是所有的时候都应该选择尾递归
2009-07-08 17:06 1013要实现一个函数,参数是一个list,结果是将list里每个数字 ... -
erlang 中case语句的使用
2009-07-07 13:16 5953在erlang中,至少有三种可互换的流程控制方式:函数声明上的 ... -
erlang 中带下划线变量的使用
2009-07-03 15:39 3623在erlang里'_'是一个特殊的变量(其实erlang里不应 ... -
Erlang 基础学习 1
2008-09-16 02:55 1023Erlang Day 1 基础• 容错,在多核CPU上性能好, ... -
Erlang 基础学习 2 简单的程序
2008-09-16 07:49 1075Erlang Sequential ProgrammingMo ... -
Erlang 基础学习 3 异常处理
2008-09-17 08:09 1405Erlang Day 3 异常处理• 三种方式可以抛出异常• ... -
Erlang 基础学习 4 Advanced Sequential Programming
2008-09-17 08:11 1513Day 4 Advanced Sequential Progr ... -
Erlang 基础学习 5 编译和运行
2008-09-17 09:40 1819如何退出erlang 的shell• ... -
Erlang 基础学习 6 Concurrent Programming
2008-09-18 06:14 1325好戏开始了Erlang 的程序由很多process组成,这些p ... -
Erlang 基础学习 7 Errors in Concurrent Programs
2008-09-19 03:48 1911Linking Processes• 进程可以调用link(P ... -
Erlang 基础学习 8 Distributed programming
2008-09-25 06:22 1496Distributed Programming为啥需要分布式的 ...
相关推荐
通过对以上知识点的学习和实践,开发者可以利用Erlang的强大功能来创建高可靠性、高并发的分布式系统。 erlang-book-part1.pdf可能涵盖其中的一些或全部内容,为读者提供全面的Erlang编程指导。
### Erlang Programming 导读.pdf 知识点详解 #### 一、Erlang简介与特点 **Erlang**是一种通用的、并发性强的、容错性高的编程语言,适用于构建分布式系统的软件。它最初由爱立信公司开发,用于解决电信系统中的...
从目录可以看出,本书首先介绍了Erlang的基础概念和安装指南,随后逐步深入到更高级的主题和技术细节。通过这种方式,读者可以从零开始学习Erlang,并逐步掌握其核心功能和编程技巧。 ### 7. 特别准备 文件中多次...
Joe的那篇erlang论文 Programming Erlang + 源码包 Erlang Programming Concurrent Programming in Erlang efficiecy guide 资源齐全.希望能帮到你.
通过阅读《Programming Erlang》,读者可以深入了解这些特性,并学习如何运用它们来解决实际问题。书中的例子涵盖了从基本的函数式编程概念到复杂的并发系统设计,对于任何想要涉足Erlang或对函数式编程感兴趣的人来...
这是《 Erlang编程语言》的上一页,我们正在处理中,将那里的所有书籍都转换为新页面。 请再次检查此页面!!!
### 关于《Pragmatic Programming ...总之,《Pragmatic Programming Erlang 第二版》是一本非常值得推荐的Erlang学习资料,无论你是刚刚接触Erlang的新手还是想要深入了解Erlang的资深开发者,都能从中获益良多。
[奥莱理] Building Web Applications with Erlang Working with REST and Web Sockets on Yaws (E-Book) ☆ 出版信息:☆ [作者信息] Zachary Kessin [出版机构] 奥莱理 [出版日期] 2012年06月14日 [图书页数] ...
《编程Erlang》是Joe ...通过对《编程Erlang》源码的学习,我们可以深入了解Erlang的精髓,掌握如何构建高效、健壮的并发系统,以及如何利用其特性解决实际问题。源码阅读不仅是理论知识的深化,更是实践技能的提升。
资源名称:Erlang语音学习资料汇总资源目录:【】Erlang程序设计【】[ManningPublications]ErlangandOTPinAction【】[NoStarchPress]LearnYouSomeErlangforGreatGood!ABeginner'sGuide【】[O'ReillyMedia]...
图灵图书值得一看,希望对大家有用,通俗易懂,涵盖了erlang的方方面面
"Erlang中文基础教程" Erlang 编程语言是一种功能强大且灵活的编程语言,它提供了一个交互式的 shell 环境,允许用户在其中编写和运行代码。 Erlang Shell 是一个命令行交互环境,类似于 UNIX 和 LINUX 系统的...
理解函数式编程的核心概念,如不可变数据、高阶函数和模式匹配,是学习Erlang的基础。 2. **过程与并发**:Erlang中的并发是通过轻量级进程(Lightweight Processes, LWP)实现的,每个进程有自己的堆栈和消息队列...
在开始学习并发之前,理解Erlang中的顺序编程是非常重要的基础。这部分介绍了基本的编程概念,如变量、数据类型、流程控制等。例如,在Erlang中,所有变量都是只读的,这意味着一旦一个变量被赋值后就不能改变其值,...
Introducing Erlang Getting Started in Functional Programming(2nd) 英文epub 第2版 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除