首页 > 代码库 > [Erlang之旅 0009] socket 通讯

[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     receive31         {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) of50         [] -> 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      receive72          {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}]) of20         {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     receive33         {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").okClient receive msg:<<"abcdaeafad">>