Erlang中粘包处理

转载自 http://www.qingliangcn.com/?s=%E7%B2%98%E5%8C%85

 

 

recv(ClientSockPacketLenOldRemain

  when is_integer(PacketLenOldand is_binary(Remain) ->

case gen_tcp:recv(ClientSock0of

{ok, B} ->

Bin = <<Remain/binary, B/binary>>,

%% read the packet length

if PacketLenOld =:= 0 andalso erlang:byte_size(Bin) > 2

 -> <<PacketLen:16Remain2/binary>> = Bin;

   true -> Remain2 = BinPacketLen = PacketLenOld

end,

?DEBUG("packet length ~p", [PacketLen]),

if 

erlang:byte_size(Remain2) >= PacketLen

  -> {RealDataNext} = split_binary(Remain2PacketLen),

 MainData = decode(RealData),

 {ok, MainData0Next};

true -> {continue, PacketLenRemain2}

end;

{error, closed} ->

?DEBUG("socket closed ~p ~n", [ClientSock]),

{error, closed};

{error, Reason} ->

?ERROR_MSG("socket closed ~p with reason: ~p ~n", [ClientSockReason]),

{error, Reason}

end.

翻了翻文档发现实际上在erlang中没有必要这样麻烦

The Length argument is only meaningful when the socket is in 

raw mode and denotes the number of bytes to read. 

If Length = 0, all available bytes are returned. 

If Length > 0, exactly Length bytes are returned, or an error;

recv(ClientSock) ->

case gen_tcp:recv(ClientSock2of

{ok, PacketLenBin} -> <<PacketLen:16>> = PacketLenBin,

case gen_tcp:recv(ClientSockPacketLenof

{ok, RealData} ->

?DEBUG("recv data ~p", [RealData]),

{ok, decode(RealData)};

{error, Reason} ->

?ERROR_MSG("read packet data failed with reason: ~p", [Reason]),

{error, Reason}

end;

{error, Reason} -> 

?ERROR_MSG("read packet length failed with reason: ~p", [Reason]),

{error, Reason}

end.

<!--EndFragment-->

 

你可能感兴趣的:(erlang)