首页 > 代码库 > erlang的tcp服务器模板

erlang的tcp服务器模板

网上抄来的,经过一系列调试,7788大概明白了,直接贴代码

 

tcp_server_app.erl

-module(tcp_server_app).-behaviour(application).-export([start/2, stop/1]).-define(DEF_PORT,    2222).start(_Type, _Args) ->    Opts = [                binary,                {packet, 4},                {reuseaddr, true},                {keepalive, true},                {packet_size,4096},                {backlog, 30},                {active, false}            ],    ListenPort = get_app_env(listen_port, ?DEF_PORT),    {ok, LSock} = gen_tcp:listen(ListenPort, Opts),    case tcp_server_handler_sup:start_link(LSock) of        {ok, Pid} ->            tcp_server_handler_sup:start_child(),            {ok, Pid};        Other ->            {error, Other}    end.stop(_S) ->    ok.get_app_env(Opt, Default) ->    case application:get_env(application:get_application(), Opt) of        {ok, Val} -> Val;        _ ->            case init:get_argument(Opt) of                [[Val | _]] -> Val;                error       -> Default            end    end.

 

tcp_server_handler_sup.erl

-module(tcp_server_handler_sup).-behaviour(supervisor).-export([start_link/1, start_child/0]).-export([init/1]).-define(SERVER, ?MODULE).start_link(LSock) ->    supervisor:start_link({local, ?SERVER}, ?MODULE, [LSock]).start_child() ->    supervisor:start_child(?SERVER, []).init([LSock]) ->    Server = {tcp_server_handler, {tcp_server_handler, start_link, [LSock]},        temporary, brutal_kill, worker, [tcp_server_handler]},    Children = [Server],    RestartStrategy = {simple_one_for_one, 0, 1},    {ok, {RestartStrategy, Children}}.

 

tcp_server_handler.erl

-module(tcp_server_handler).-behaviour(gen_server).-export([start_link/1]).-export([init/1, handle_call/3, handle_cast/2, handle_info/2,terminate/2, code_change/3]).-record(state, {lSock, socket, addr}).start_link(LSock) ->    gen_server:start_link(?MODULE, [LSock], []).init([Socket]) ->    Opts = [        binary,        {packet, 4},        {reuseaddr, true},        {keepalive, true},        {packet_size,4096},        {backlog, 30},        {active, once}    ],    inet:setopts(Socket,Opts),    {ok, #state{lSock = Socket}, 0}.handle_call(Msg, _From, State) ->    {reply, {ok, Msg}, State}.handle_cast(stop, State) ->    {stop, normal, State}.handle_info({tcp, Socket, Data}, State) ->    inet:setopts(Socket, [{active, once}]),    io:format("~p got message ~p\n", [self(), Data]),    ok = gen_tcp:send(Socket, <<"Echo back : ", Data/binary>>),    {noreply, State};handle_info({tcp_closed, Socket}, #state{addr=Addr} = StateData) ->    error_logger:info_msg("~p Client ~p disconnected.\n", [self(), Addr]),    {stop, normal, StateData};handle_info(timeout, #state{lSock = LSock} = State) ->    {ok, ClientSocket} = gen_tcp:accept(LSock),    {ok, {IP, Port}} = inet:peername(ClientSocket),    io:format("client connected ~p:~p\n",[IP,Port]),    tcp_server_handler_sup:start_child(),    {noreply, State#state{socket=ClientSocket, addr=IP}};handle_info(_Info, StateData) ->    {noreply, StateData}.terminate(_Reason, #state{socket=Socket}) ->    (catch gen_tcp:close(Socket)),    ok.code_change(_OldVsn, State, _Extra) ->    {ok, State}.

erlang的自动处理粘包确实很有效,{packet,1},{packet,2},{packet,4}确实很有效,对应着手工添加的包头,用来解决粘包问题。

erlang的tcp服务器模板