programming erlang ch14 2 - andstudy/forge GitHub Wiki
-
socket_examples.erl
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. -
์คํํด๋ณด๊ธฐ
socket_examples:nano_get_url(). RESULT = socket_examples:nano_get_url("www.naver.com"). io:format("~p~n",[RESULT]). string:tokens(binary_to_list(RESULT),"\r\n").
-
eval ์๋ฒ
start_nano_server() -> {ok, Listen} = gen_tcp:listen(2345, [binary, {packet, 4}, %% (6) {reuseaddr, true}, {active, true}]), {ok, Socket} = gen_tcp:accept(Listen), %% (7) gen_tcp:close(Listen), %% (8) loop(Socket). loop(Socket) -> receive {tcp, Socket, Bin} -> io:format("Server received binary = ~p~n",[Bin]), Str = binary_to_term(Bin), %% (9) io:format("Server (unpacked) ~p~n",[Str]), Reply = lib_misc:string2value(Str), %% (10) io:format("Server replying = ~p~n",[Reply]), gen_tcp:send(Socket, term_to_binary(Reply)), %% (11) loop(Socket); {tcp_closed, Socket} -> io:format("Server socket closed~n") end. -
ํด๋ผ์ด์ธํธ
nano_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 received binary = ~p~n",[Bin]), Val = binary_to_term(Bin), io:format("Client result = ~p~n",[Val]), gen_tcp:close(Socket) end. -
์๋ฒ ์คํํ๊ธฐ
c("socket_examples"). c("lib_misc"). socket_examples:start_nano_server(). -
ํด๋ผ์ด์ธํธ ์คํํ๊ธฐ
c("socket_examples"). socket_examples:nano_client_eval("list_to_tuple([2+3*4,10+20])").
-
์์ฐจ์๋ฒ - ํ ๋ฒ์ ํ๋์ ์ ์๋ง ๋ฐ๋ ์๋ฒ
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). loop(..) -> %..์๋ ๋ก์ง -
๋ณ๋ ฌ์๋ฒ - ๋์์ ๋ค์์ ๋ณ๋ ฌ ์ ์์ ๋ฐ๋ ์๋ฒ
start_parallel_server() -> {ok, Listen} = gen_tcp:listen(...), spawn( fun() -> par_connect(Listen) end ). par_connect(Listen) -> {ok, Socket} = gen_tcp:accecpt(Listen), spawn( fun() -> par_connect(Listen) end ). loop(Socket). loop(..) -> %..์๋ ๋ก์ง
- ์ผ๋ญ ์์ผ์ ์ธ๊ฐ์ง ๋ชจ๋
| ์ต์ | ๋ชจ๋์ค๋ช | ๋ฐ์ดํฐ ์์ |
|---|---|---|
| {active,true} | ๋ฅ๋์ ๋ฉ์ธ์ง ์์ (๋ ผ๋ธ๋กํน) | {tcp, Socket, Data} ๋ก ์ ๋ฌ ๋ฐ์ |
| {active,false} | ์๋์ ๋ฉ์ธ์ง ์์ (๋ธ๋กํน) | gen_tcp:recv{Socket,N) ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ด |
| {active,once} | ํผํฉํ ๋ฉ์ธ์ง ์์ (๋ถ๋ถ ๋ธ๋กํน) | ํ๋ฒ๋ง ๋ฐ์ดํฐ๊ฐ {tcp, Socket, Data}๋ก ์์ |
{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.
{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.
{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.
@spec inet:peername(Socket) -> {ok, {IP_Address, Port}) | {error,Why}
error_test() ->
spawn(fun() -> error_test_server() end),
lib_misc:sleep(2000),
{ok,Socket} = gen_tcp:connect("localhost",4321,[binary, {packet, 2}]),
io:format("connected to:~p~n",[Socket]),
gen_tcp:send(Socket, <<"123">>),
receive
Any ->
io:format("Any=~p~n",[Any])
end.
error_test_server() ->
{ok, Listen} = gen_tcp:listen(4321, [binary,{packet,2}]),
{ok, Socket} = gen_tcp:accept(Listen),
error_test_server_loop(Socket).
error_test_server_loop(Socket) ->
receive
{tcp, Socket, Data} ->
io:format("received:~p~n",[Data]),
atom_to_list(Data),
error_test_server_loop(Socket)
end.
-
UDP ์๋ฒ
server(Port) -> {ok,Socket} = gen_udp:open(Port, {binary}), loop(Socket). loop(Socket) -> recive {udp, Socket, Host, Port, Bin} -> BinReply = .... gen_udp:send(Socket, Host, Port, BinReply), loop(Socket) end. -
UDP ํด๋ผ์ด์ธํธ
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
-
udp_test.erl
start_server() -> spawn(fun() -> server(4000) end). %% The server server(Port) -> {ok, Socket} = gen_udp:open(Port, [binary]), io:format("server opened socket:~p~n",[Socket]), loop(Socket). loop(Socket) -> receive {udp, Socket, Host, Port, Bin} = Msg -> io:format("server received:~p~n",[Msg]), N = binary_to_term(Bin), Fac = fac(N), gen_udp:send(Socket, Host, Port, term_to_binary(Fac)), loop(Socket) end. fac(0) -> 1; fac(N) -> N * fac(N-1). %% The client client(N) -> {ok, Socket} = gen_udp:open(0, [binary]), io:format("client opened socket=~p~n",[Socket]), ok = gen_udp:send(Socket, "localhost", 4000, term_to_binary(N)), Value = receive {udp, Socket, _, _, Bin} = Msg -> io:format("client received:~p~n",[Msg]), binary_to_term(Bin) after 2000 -> 0 end, gen_udp:close(Socket), Value.