3.Socket
来源:互联网 发布:阿沁的淘宝店叫什么 编辑:程序博客网 时间:2024/05/17 05:11
说到socket就会想到tcp、udp、http协议,先来分析一下erlang项目中如何使用tcp socket。
RabbitMQ项目中使用了prim_inet:async_accept/2、prim_inet:async_recv/3等方法,这些是相对比较底层的api,在erlang官方文档中并没有介绍,不过我们可以通过源码看到,最终会进到erlang:port_control/3函数,与端口进行交互。然后我们进到gen_tcp模块,可以看到无论是调用了inet_tcp还是inet6_tcp,最终还是会回到prim_inet模块。因此gen_tcp是对prim_inet进行包装,是更高层的socket调用模块,用gen_tcp写socket层,代码也会更清理明了。使用gen_tcp模块收到内核协议栈过来完整的封包的时候,可以通过init:setopts/2设置接收消息的方式。官方文档:http://www.erlang.org/doc/man/inet.html
{active, true | false | once | N}:true时,所有收到的信息都会被传递到接收进程;false时,只能接收通过gen_tcp:recv/2,3, gen_udp:recv/2,3 or gen_sctp:recv/1,2等函数接收到信息;once时,每次收到信息后需要手动重置,以待下次接收。这里讨论一下N,N可以理解为once的扩展,once是每收到一条信息都需要重置,而N则是收到N条信息后重置一次。参数N是OTP 17.0以后的版本才能使用。下面有个简单的例子:
-module(sockettcp). -export([start/0]). start() -> {ok, LSock} = gen_tcp:listen(1234, [binary, {packet, 0},{active, false}]), io:format("listen(~p) on ~p~n",[LSock, 1234]), 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("(~p)recv:~p~n",[Socket, Data]); {tcp_passive,Socket} -> inet:setopts(ASock, [{active, 3}]), io:format("tcp_passive:~p~n",[Socket]); Err -> io:format("error:~p~n",[Err]) end, do_loop(ASock).再开一个shell作为客户端输入:
{ok,S} = gen_tcp:connect({127,0,0,1},1234,[{packet,0}]).gen_tcp:send(S, integer_to_binary(1)).gen_tcp:send(S, integer_to_binary(1)).gen_tcp:send(S, integer_to_binary(1)).gen_tcp:send(S, integer_to_binary(1)).可以看到每间隔3个包,需要重置一次参数。
0 0
- 3.Socket
- 2-3.socket通信
- socket
- socket
- Socket
- Socket
- Socket
- Socket
- Socket
- Socket
- socket
- Socket
- Socket
- Socket
- Socket
- socket
- socket
- socket
- 01串排序
- 提高 ASP.NET Web 应用性能的 24 种方法和技巧
- c++学习书籍
- Java线程--思维导图
- Dijkstra Algorithm 实现
- 3.Socket
- HTML--思维导图
- POJ 3671 Dining Cows
- Ubuntu安装Java
- 4.Mysql驱动
- VS插件,好用,提高代码效率。Productivity Power Tools
- java Arrays类使用方法
- 5.集群
- CSS-思维导图