<div dir="ltr"><div>I worte a tcp proxy to forward data from peer to peer, but i find the CPU usage of beam is high in test</div>
<div>The client make 1000 connections per second and get 16K data from server, and the server send 8K to client per second, because we want to decrease the traffic.</div>
<div>And the compute's CPU is Intel(R) Xeon(TM) CPU 3.20GHz, so the proxy's usage is on avenage 26%</div>
<div>Is my codes have some problem or erlang need some optimization.</div>
<div>Anyone can tell me </div>
<div> </div>
<div>here is my codes</div>
<div> </div>
<div>%%%----------------------------------------------------------------------<br>%%% File    : tcp.erl<br>%%% Author  : Zhao Liang<<a href="mailto:realaqura@gmail.com">realaqura@gmail.com</a>><br>%%%----------------------------------------------------------------------</div>

<div>-module(tcp).<br>-author(<a href="mailto:'realaqura@gmail.com'">'realaqura@gmail.com'</a>).</div>
<div>-compile(export_all).</div>
<div><br>-define(MAIN_MODULE,  tcp).</div>
<div><br>-record(cfg, {<br> listen_port = 10080,<br> idle = 30000}).</div>
<div><br>main(Port) -><br>    Cfg = #cfg{listen_port=Port},<br>    case gen_tcp:listen(Port, [{reuseaddr,true}, {active,false}, {backlog,64}, binary]) of<br>        {ok, LSock} -></div>
<div>            create_accept_thread(LSock, Cfg, self()),<br>            tcp_ctl_loop(LSock, Cfg, self());<br>        ERR -> ERR<br>    end.</div>
<div>tcp_ctl_loop(LSock, Cfg, Self) -><br>    receive <br>    {_, next} -><br>        create_accept_thread(LSock, Cfg, Self),</div>
<div>        tcp_ctl_loop(LSock, Cfg, Self);<br>    _ -><br>        tcp_ctl_loop(LSock, Cfg, Self)<br>    end.</div>
<div>create_accept_thread(LSock, Cfg, Pid) -><br>    spawn_link(?MAIN_MODULE, accept_thread, [LSock, Cfg, Pid]).</div>
<div>accept_thread(LSock, Cfg, Parent) -><br>    accept_loop(LSock, Cfg, Parent).</div>
<div>accept_loop(LSock, Cfg, Parent) -><br>    case prim_inet:async_accept(LSock, -1) of<br>        {ok, Ref} -><br>            receive<br>                {inet_async, LSock, Ref, {ok,CSock}} -><br>                    Parent ! {self(), next},<br>
                    tcp_start(CSock, Cfg);<br>                {inet_async, LSock, Ref, _} -><br>                    accept_loop(LSock, Cfg, Parent)<br>            end;<br>        _ -><br>            accept_loop(LSock, Cfg, Parent)<br>
    end.</div>
<div>tcp_start(CSock, Cfg) -><br>    case prim_inet:getopts(CSock, [original_dst]) of<br>        {ok, [{original_dst, {Oport, Oip}}]} -><br>            case gen_tcp:connect(Oip, Oport, [{active,true}, {packet,raw}, binary], Cfg#cfg.idle) of<br>
                {ok, SSock} -><br>                    tcp_start(CSock, SSock, Cfg);<br>                _ -><br>                    inet:tcp_close(CSock)<br>            end;<br>        _ -> <br>            inet:tcp_close(CSock)<br>
    end.<br>tcp_start(CSock, SSock, Cfg) -><br>    inet:setopts(CSock, [{active, true}, {packet,raw}, binary]),<br>    tcp_data_loop(CSock, SSock, Cfg).</div>
<div>tcp_data_loop(CSock, SSock, Cfg) -><br>    receive <br>        {tcp, Socket, Data} -><br>            if<br>                Socket == CSock -><br>                    case prim_inet:send(SSock, Data) of<br>                        ok -><br>
                            tcp_data_loop(CSock, SSock, Cfg);<br>                        _ -><br>                            gen_tcp:close(CSock),<br>                            gen_tcp:close(SSock)<br>                    end;<br>
                Socket == SSock -><br>                    case prim_inet:send(CSock, Data) of<br>                        ok -><br>                            tcp_data_loop(CSock, SSock, Cfg);<br>                        _ -><br>
                            gen_tcp:close(CSock),<br>                            gen_tcp:close(SSock)<br>                    end;<br>                true -><br>                    tcp_data_loop(CSock, SSock, Cfg)<br>            end;<br>
        {tcp_closed, Socket} -><br>            if<br>                Socket == CSock -><br>                    gen_tcp:close(SSock);<br>                Socket == SSock -><br>                    gen_tcp:close(CSock);<br>
                true -><br>                    gen_tcp:close(CSock),<br>                    gen_tcp:close(SSock)<br>            end;<br>         _ -><br>            gen_tcp:close(CSock),<br>            gen_tcp:close(SSock)<br>
    after<br>        Cfg#cfg.idle -><br>            gen_tcp:close(CSock),<br>            gen_tcp:close(SSock)<br>    end.<br></div></div>