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


分享给朋友:
您可能感兴趣的文章:
随机阅读: