码迷,mamicode.com
首页 > 其他好文 > 详细

erlang的tcp服务器模板

时间:2014-11-05 21:04:55      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:style   blog   io   color   ar   os   for   sp   div   

网上抄来的,经过一系列调试,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服务器模板

标签:style   blog   io   color   ar   os   for   sp   div   

原文地址:http://www.cnblogs.com/ziyouchutuwenwu/p/4077182.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!