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).