专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > Erlang

[Erlang人迹 0009] socket 通讯

发布时间:2011-06-29 17:49:23 文章来源:www.iduyao.cn 采编人员:星星草
[Erlang脚印 0009] socket 通讯

  前面学习完了gen_server 、gen_tcp 现在做一个简易的socket通讯,服务端将接收到的信息返回给客户端,具体代码如下:

服务端:

 1 -module(tcp_socket3).
 2 -behaviour(gen_server).
 3 
 4 -export([start/0, login/2, stop/0]).
 5 -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
 6 
 7 -export([start_client/0]).
 8 
 9 -record(users, {id, name, pwd}).
10 
11 start() ->
12     start(6000).
13 
14 start(Port) ->
15     gen_server:start_link({local, ?MODULE}, ?MODULE, [], []),
16     {ok, ListenSocket} = gen_tcp:listen(Port, [binary,{packet, 0}, {active, true}]),
17     par_connect(ListenSocket).
18 
19 init([]) ->
20     ets:new(?MODULE, [set, public, named_table, {keypos, #users.id}]),
21     
22     {ok, ?MODULE}.
23 
24 par_connect(Listen) ->
25     {ok, Socket} = gen_tcp:accept(Listen),
26     spawn(fun() -> par_connect(Listen) end),
27     loop(Socket).
28 
29 loop(Socket) ->
30     receive
31         {tcp, Socket, Data} ->
32             io:format("Server receive binary:~p~n", [Data]),
33             RecStr = binary_to_list(Data),
34             io:format("Server receive binary_to_list:~p~n",[RecStr]),
35             gen_tcp:send(Socket, Data),
36             loop(Socket);
37         {tcp_closed, Socket} ->
38             io:format("Client socket closed")
39     end.
40 
41 
42 login(Id,Pwd) ->
43     gen_server:call(?MODULE,{login, Id, Pwd}).
44 
45 stop() ->
46     gen_server:call(?MODULE, stop).
47 
48 handle_call({login, Id, Pwd}, _From, Tab) ->
49     Reply = case ets:lookup(Tab, Id) of
50         [] -> User1=#users{id=Id, name=Id, pwd=Pwd},
51             ets:insert(Tab, User1),
52             io:format("Tab content:~p~n",[ets:tab2list(Tab)])
53     end,
54     {reply, Reply, Tab};
55 handle_call(stop, _From, Tab) ->
56     {stop, normal, stopped, Tab}.
57 
58 handle_cast(_Msg, State) -> {noreply, State}.
59 handle_info(_Info, State) -> {noreply, State}.
60 terminate(_Reason, State) ->
61     ok.
62 
63 code_change(_OldVsn, State, _Extra) -> {ok, State}.
64 
65 start_client() ->
66     start_client("localhost", 6000).
67 
68 start_client(Address, Port) ->
69     {ok, Socket} = gen_tcp:connect(Address, Port, [binary, {packet, 0}, {active, true}]),
70      ok=gen_tcp:send(Socket, list_to_binary("{login,tom, tom1}")),
71      receive
72          {tcp, Socket, Data} ->
73               io:format("Client receive binary:~p~n", [Data]),
74               RecStr = binary_to_list(Data),
75               io:format("Client receive binary_to_list:~p~n", [RecStr]),
76               gen_tcp:close(Socket)
77         end.

 客户端:

 1 -module(tcp_client).
 2 -behaviour(gen_server).
 3 
 4 -export([start/0, start/2, stop/0, send_data/1]).
 5 -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
 6 
 7 -define(HOSTIP,"127.0.0.1").
 8 -define(PORT, 8000).
 9 
10 -record(state, {socket}).
11 
12 start() ->
13     start(?HOSTIP, ?PORT).
14 
15 start(HOSTIP, PORT) ->
16     gen_server:start_link({local, ?MODULE}, ?MODULE,[HOSTIP, PORT], []).
17 
18 init([HostIP, Port]) ->
19     case gen_tcp:connect(HostIP, Port, [binary, {packet, 0}, {active, true}]) of
20         {ok, Socket} ->
21             io:format("Connect host success, start to receive message:~n"),
22             spawn(fun() ->loop(Socket) end),
23             {ok, #state{socket = Socket}};
24         {error, Reason} ->
25             io:format("Connect host error:~p~n", [Reason]),
26             {stop, Reason}
27     end.
28     
29 
30 loop(Socket) ->
31     io:format("loop start ~n"),
32     receive
33         {tcp, Socket, Data} ->
34             io:format("Client receive binary:~p~n", [Data]),
35             loop(Socket);
36         {tcp_closed, Socket} ->
37             io:format("Client is closed~n"),
38             stop()
39     end.
40 
41 stop() ->
42     gen_server:cast(?MODULE, stop).
43 
44 send_data(Msg) ->
45     gen_server:call(?MODULE,Msg).
46 
47 handle_call(Msg, _From, State) ->
48     Reply = gen_tcp:send(State#state.socket, list_to_binary(Msg)),
49     {reply,Reply, State}.
50 handle_cast(stop, State) ->
51     {stop, normal, State}.
52 handle_info({tcp,Socket, RawData}, State) ->
53     io:format("Client receive msg:~p~n", [RawData]),      %% 处理接收到的信息
54     {noreply, State};
55 handle_info({tcp_closed, _Socket}, State) ->
56     stop(),
57     {noreply, State}.
58 terminate(_Reason, _State) ->
59     ok.
60 code_change(_OldVsn, State, Extra) ->
61     {ok, State}.

运行服务端:

2> c(tcp_socket3).
tcp_socket3.erl:60: Warning: variable 'State' is unused
{ok,tcp_socket3}
3> tcp_socket3:start().
Server receive binary:<<"abcdaeafad">>
Server receive binary_to_list:"abcdaeafad"

运行客户端:

8> tcp_client:start("127.0.0.1", 6000).
Connect host success, start to receive message:
loop start 
{ok,<0.52.0>}
9> tcp_client:send_data("abcdaeafad").
ok
Client receive msg:<<"abcdaeafad">>
友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

热门推荐: