erlang TCP socket 沾包断包处理

先贴code, 参照gen_tcp范例编写
server.erl:
-module(server).
-compile(export_all).

start(Num,LPort) ->
    case gen_tcp:listen(LPort,[{active, false},{packet,2}]) of
        {ok, ListenSock} ->
            start_servers(Num,ListenSock),
            {ok, Port} = inet:port(ListenSock),
            Port;
        {error,Reason} ->
            {error,Reason}
    end.

start_servers(0,_) ->
    ok;
start_servers(Num,LS) ->
    spawn(?MODULE,server,[LS]),
    start_servers(Num-1,LS).

server(LS) ->
    case gen_tcp:accept(LS) of
        {ok,S} ->
            loop(S),
            server(LS);
        Other ->
            io:format("accept returned ~w - goodbye!~n",[Other]),
            ok
    end.

loop(S) ->
    inet:setopts(S,[{active,once}]),
    receive
        {tcp,S,Data} ->
			io:format("recv tcp data~n"),
			io:format("~p~n~w~n", [Data, Data]),
            gen_tcp:send(S,<<"world">>),
            loop(S);
        {tcp_closed,S} ->
            io:format("Socket ~w closed [~w]~n",[S,self()]),
            ok
    end.


client.erl:
-module(client).
-compile(export_all).

test_packet_splicing(PortNo) ->
    {ok,Sock} = gen_tcp:connect("192.168.1.2", PortNo, [binary, {active, false}]),
	gen_tcp:send(Sock, <<0,5,104,101,108,108,111, 0,5,104,101,108,108,111>>),
    A = gen_tcp:recv(Sock,0),
    gen_tcp:close(Sock),
    A.

test_package_spliting(PortNo) ->
    {ok,Sock} = gen_tcp:connect("192.168.1.2", PortNo, [binary, {active, false}, {delay_send, false}]),
	gen_tcp:send(Sock, <<0,5,104,101>>),
	gen_tcp:send(Sock, <<108,108,111>>),
    A = gen_tcp:recv(Sock,0),
    gen_tcp:close(Sock),
    A.


server:start(10, 81000).
client:test_packet_splicing(8100).
client:test_package_spliting(8100).
贴结果:
server输出

抓包:

沾包报文:

断包报文:



So, 直接在处理socket的process中大胆进行处理吧!

转载请标明出处http://ziplee.iteye.com/blogs/2198614


猜你喜欢

转载自ziplee.iteye.com/blog/2198614
今日推荐