首页 > 代码库 > [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">>
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。