[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">>

你可能感兴趣的:(socket)