zoukankan      html  css  js  c++  java
  • [erlang] Erlang TCP(gen_tcp)

      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
    >

    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> 
  • 相关阅读:
    Ubuntu11.04中如何将pycharm添加到系统的“应用程序”菜单里 (pycharm已成功安装)
    Office 365 离线安装
    关于wxpy,使用Python玩转微信的问题
    python3安装scrapy问题解决
    python打包exe文件-ImportError: No module named 'queue'
    Linux TOP命令按内存占用排序和按CPU占用排序
    设置iptables允许ssh、http、ftp服务
    重置linux mysql root密码
    linux.go
    return_fun.go 源码阅读
  • 原文地址:https://www.cnblogs.com/bluefrog/p/2511794.html
Copyright © 2011-2022 走看看