1 -module(socket_example). 2 -compile(export_all). 3 4 nano_get_url() -> 5 nano_get_url("www.google.com"). 6 7 nano_get_url(URL) -> 8 {ok,Socket} = gen_tcp:connect(URL,80,[binary,{packet,0}]), 9 ok = gen_tcp:send(Socket,"GET / HTTP/1.0\r\n\r\n"), 10 receive_data(Socket,[]). 11 12 receive_data(Socket,SoFar) -> 13 receive 14 {tcp,Socket,Bin} -> 15 receive_data(Socket,[Bin|SoFar]); 16 {tcp_closed,Socket} -> 17 list_to_binary(lists:reverse(SoFar)) 18 end. 19 20 start_nano_server() -> 21 %% 返回 {ok,Socket} 或 error,Why 22 case gen_tcp:listen(2345,[binary,{packet,4}, %% 每个应用程序消息都从一个4字节长的头部开始 23 {reuseaddr,true}, %% 24 {active,true}]) of %% {active,true} 创建一个主动套字节(非阻塞) 25 %% {active,false} 创建一个被动套字节(阻塞) 26 %% {active,once} 创建一个主动套字节仅接收一条消息,如想接收下一条必须再次激活(半阻塞) 27 {ok,Listen} -> 28 case gen_tcp:accept(Listen) of %% 等待暂停并等待一个连接 29 {ok,Socket} -> 30 gen_tcp:close(Listen), %% 关闭监听,服务器不会继续处于监听状态,也无法建立任何新的连接 31 loop(Socket); 32 {error,Why} -> 33 io:format("~p~n",[Why]) 34 end; 35 {error,Why} -> 36 io:format("~p~n",[Why]) 37 end. 38 39 loop(Socket) -> 40 receive 41 {tcp,Socket,Bin} -> 42 io:format("Server received binary = ~p~n",[Bin]), 43 Str = binary_to_term(Bin), 44 io:format("Server (unpacked) ~p~n",[Str]), 45 Reply = Str, 46 timer:sleep(5000), 47 %%Reply = lib_misc:string2value(Str), 48 io:format("Server replying = ~p~n",[Reply]), 49 gen_tcp:send(Socket,term_to_binary(Reply)), 50 loop(Socket); 51 {tcp_closed,Socket} -> 52 io:format("Server socket closed~n") 53 end. 54 55 nano_client_eval(Str) -> 56 {ok,Socket} = gen_tcp:connect("localhost",2345,[binary,{packet,4}]), 57 ok = gen_tcp:send(Socket,term_to_binary(Str)), 58 receive 59 {tcp,Socket,Bin} -> 60 io:format("Client received binary = ~p~n",[Bin]), 61 Val = binary_to_term(Bin), 62 io:format("Client result = ~p~n",[Val]), 63 gen_tcp:close(Socket) 64 end. 65 66 %% 顺序型服务器(一个服务器一次只接收一个连接) 67 start_seq_server() -> 68 case gen_tcp:listen(2345,[binary,{packet,4}, %% 每个应用程序消息都从一个4字节长的头部开始 69 {reuseaddr,true}, %% 70 {active,true}]) of 71 {ok,Listen} -> 72 seq_loop(Listen); 73 {error,Why} -> 74 io:format("~p~n",[Why]) 75 end. 76 77 seq_loop(Listen) -> 78 case gen_tcp:accept(Listen) of %% 等待暂停并等待一个连接 79 {ok,Socket} -> 80 loop(Socket), 81 seq_loop(Listen); 82 {error,Why} -> 83 io:format("~p~n",[Why]) 84 end. 85 86 %% 并行服务器 87 start_parallel_server() -> 88 case gen_tcp:listen(2345,[binary,{packet,4}, %% 每个应用程序消息都从一个4字节长的头部开始 89 {reuseaddr,true}, %% 90 {active,true}]) of 91 {ok,Listen} -> 92 spawn(fun()-> par_connect(Listen) end); 93 {error,Why} -> 94 io:format("~p~n",[Why]) 95 end. 96 97 par_connect(Listen) -> 98 case gen_tcp:accept(Listen) of %% 等待暂停并等待一个连接 99 {ok,Socket} -> 100 spawn(fun() -> par_connect(Listen) end), 101 loop(Socket); 102 {error,Why} -> 103 io:format("~p~n",[Why]) 104 end.
TCP服务器结果
server
Eshell V5.8.4 (abort with ^G) 1> c(socket_example). {ok,socket_example} 2> socket_example:start_nano_server(). Server received binary = <<131,107,0,4,49,50,51,52>> Server (unpacked) "1234" Server replying = "1234" Server socket closed ok >3
client
Eshell V5.8.4 (abort with ^G) 1> c(socket_example). {ok,socket_example} 2> socket_example:nano_client_eval("1234"). Client received binary = <<131,107,0,4,49,50,51,52>> Client result = "1234"
顺序服务器
server
Eshell V5.8.4 (abort with ^G) 1> socket_example:start_seq_server(). Server received binary = <<131,107,0,4,49,50,51,52>> Server (unpacked) "1234" Server replying = "1234" Server socket closed Server received binary = <<131,107,0,4,52,51,50,49>> Server (unpacked) "4321" Server replying = "4321" Server socket closed
client1
Eshell V5.8.4 (abort with ^G) 1> socket_example:nano_client_eval("1234"). Client received binary = <<131,107,0,4,49,50,51,52>> Client result = "1234" ok 2>
client2
Eshell V5.8.4 (abort with ^G) 1> socket_example:nano_client_eval("4321"). Client received binary = <<131,107,0,4,52,51,50,49>> Client result = "4321" ok 2>
并行服务器
server
Eshell V5.8.4 (abort with ^G) 1> socket_example:start_parallel_server(). <0.34.0> Server received binary = <<131,107,0,4,49,50,51,52>> Server (unpacked) "1234" Server received binary = <<131,107,0,4,52,51,50,49>> Server (unpacked) "4321" Server replying = "1234" Server socket closed Server replying = "4321" Server socket closed 2>
client1
Eshell V5.8.4 (abort with ^G) 1> socket_example:nano_client_eval("1234"). Client received binary = <<131,107,0,4,49,50,51,52>> Client result = "1234" ok 2>
client2
Eshell V5.8.4 (abort with ^G) 1> socket_example:nano_client_eval("4321"). Client received binary = <<131,107,0,4,52,51,50,49>> Client result = "4321" ok 2>