Erlang学习笔记(6) -- 套接字编程

Tcp客户端

Tcp是一种无差异的字节流,在传输过程中会被切分成任意尺寸的数据帧,所以需要做一些转换才知道, 单个请求到底有多少数据. 所以erlang发起请求 前带上的字节长度计数
所以erlang 配置发起请求,或者监听端口的时候会定义这个计数占用多少字节 ({packet,4})

-module(socket_examples).
-compile(export_all).
-import(lists, [reverse/1]).

nano_get_url() ->
    nano_get_url("www.google.com").

nano_get_url(Host) ->
    {ok,Socket} = gen_tcp:connect(Host,80,[binary, {packet, 0}]), %% (1)
    ok = gen_tcp:send(Socket, "GET / HTTP/1.0\r\n\r\n"),  %% (2)
    receive_data(Socket, []).

receive_data(Socket, SoFar) ->
    receive
    {tcp,Socket,Bin} ->    %% (3)
        receive_data(Socket, [Bin|SoFar]);
    {tcp_closed,Socket} -> %% (4)
        list_to_binary(reverse(SoFar)) %% (5)
    end.

gen_tcp : listen 方法

gen_tcp:listen(2345, [binary,{packet,4}])
gen_tcp:listen会 监听 2345端口, 传输类型是 binary, 字节长度计数 占用4字节
返回值为{ok, Listen}, 或者{error,Why}

gen:_tcp:accept (Listen)
调用 accept时, 程序会在这里暂停,并等待一个连接, 连接成功后会返回{ok, Socket}

-module(tcp).
-compile(export_all).

%%socket 服务器入口
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).


string2value(Str) ->
    {ok, Tokens, _} = erl_scan:string(Str ++ "."),
    {ok, Exprs} = erl_parse:parse_exprs(Tokens),
    Bindings = erl_eval:new_bindings(),
    {value, Value, _} = erl_eval:exprs(Exprs, Bindings),
    Value.  

loop(Socket) ->
    receive 
        {tcp, Socket, Bin} -> 
            io:format("server receive binary = ~p~n", [Bin]),
            Str = binary_to_term(Bin),
            Replay = string2value(Str),
            io:format("server replying - ~p~n", [Replay]),
            gen_tcp:send(Socket, term_to_binary(Replay)),
            loop(Socket);
        {tcp_closed, Socket} -> 
            io:format("socket server  closed")
    end.

client_eval(Str) -> 
    {ok, Socket} =  gen_tcp:connect("localhost", 2345, [binary, {packet, 4}]),
    ok = gen_tcp:send(Socket, term_to_binary(Str)),
    receive
        {tcp, Socket, Bin}->
            io:format("client receive binary = ~p~n", [Bin]),
            Val = binary_to_term(Bin),
            io:format("client result = ~p~n", [Val]),
            gen_tcp:close(Socket)
    end.




start_seq_server()->
    {ok, Listen} = gen_tcp:listen(2345, [binary, {packet, 4}, {reuseaddr, true}, {active, true}]),
    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(2345, [binary, {packet, 4}, {reuseaddr, true}, {active, true}]),
    parallel_loop(Listen).

parallel_loop(Listen) ->
    {ok, Socket} = gen_tcp:accept(Listen),
    spawn(fun()->parallel_loop(Listen) end),
    loop(Socket).
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值