decode frames
This commit is contained in:
parent
2a8ead5f01
commit
2ff9cf51ce
@ -19,8 +19,27 @@ start() ->
|
||||
do_start() ->
|
||||
Port = 1365,
|
||||
{ok, Conn} = quicer:connect("localhost", Port, [{alpn, ["punchnet/1.0"]}, {verify, none}], 5000),
|
||||
|
||||
receive
|
||||
{quic, connected, Conn} ->
|
||||
ok
|
||||
after 1000 ->
|
||||
ok
|
||||
end,
|
||||
|
||||
{ok, Stm} = quicer:start_stream(Conn, []),
|
||||
{ok, 4} = quicer:send(Stm, <<"ping">>),
|
||||
logger:debug("[quic_client] client send success"),
|
||||
receive
|
||||
{quic, stream_started, Stm} ->
|
||||
ok
|
||||
after 1000 ->
|
||||
ok
|
||||
end,
|
||||
|
||||
Data = <<"ping">>,
|
||||
Len = byte_size(Data),
|
||||
Payload = <<Len:16, Data/binary, Len:16, Data/binary>>,
|
||||
|
||||
{ok, SendLen} = quicer:send(Stm, Payload),
|
||||
logger:debug("[quic_client] client send success: ~p", [SendLen]),
|
||||
receive {quic, <<"pong">>, Stm, _Props} -> ok end,
|
||||
ok = quicer:close_connection(Conn).
|
||||
@ -11,6 +11,8 @@
|
||||
|
||||
-behaviour(gen_statem).
|
||||
|
||||
-define(MAX_FRAME_LEN, 16384).
|
||||
|
||||
%% API
|
||||
-export([start_link/1]).
|
||||
|
||||
@ -19,7 +21,9 @@
|
||||
|
||||
-record(state, {
|
||||
conn :: quicer:connection_handle(),
|
||||
stream_handle :: undefined | quicer:stream_handle()
|
||||
stream_handle :: undefined | quicer:stream_handle(),
|
||||
%% 累积器,用于处理协议framing的解析
|
||||
buf = <<>>
|
||||
}).
|
||||
|
||||
%%%===================================================================
|
||||
@ -65,11 +69,21 @@ handle_event(internal, do_init, initializing, State = #state{conn = Conn}) ->
|
||||
{stop, Reason, State}
|
||||
end;
|
||||
|
||||
%% 处理quicer相关的信息
|
||||
handle_event(info, {quic, Msg, Stream, _Props}, _StateName, State = #state{stream_handle = Stream}) ->
|
||||
logger:debug("[sdlan_quic_channel] get message: ~p", [Msg]),
|
||||
handle_event(info, {frame, Frame}, _StateName, State = #state{}) ->
|
||||
logger:debug("[sdlan_quic_channel] get frame: ~p", [Frame]),
|
||||
{keep_state, State};
|
||||
|
||||
%% 处理quicer相关的信息
|
||||
handle_event(info, {quic, Data, Stream, _Props}, _StateName, State = #state{stream_handle = Stream, buf = Buf}) ->
|
||||
logger:debug("[sdlan_quic_channel] get message: ~p", [Data]),
|
||||
case decode_frames(<<Buf/binary, Data/binary>>) of
|
||||
{error, Reason} ->
|
||||
{stop, Reason, State};
|
||||
{ok, NBuf, Frames} ->
|
||||
Actions = [{next_event, info, {frame, Frame}} || Frame <- Frames],
|
||||
{keep_state, State#state{buf = NBuf}, Actions}
|
||||
end;
|
||||
|
||||
handle_event(info, {quic_closed, Stream, _Props}, _StateName, State = #state{conn = Conn, stream_handle = Stream}) ->
|
||||
quicer:close_connection(Conn),
|
||||
{stop, connection_closed, State};
|
||||
@ -106,3 +120,16 @@ code_change(_OldVsn, StateName, State = #state{}, _Extra) ->
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
|
||||
%% 有2种情况
|
||||
%% 1. 收到了多个完整的请求
|
||||
%% 2. 不完整,则不处理
|
||||
-spec decode_frames(Buf :: binary()) -> {ok, RestBin::binary(), Frames :: list()} | {error, Reason :: any()}.
|
||||
decode_frames(Buf) when is_binary(Buf) ->
|
||||
decode_frames0(Buf, []).
|
||||
decode_frames0(<<Len:16, _/binary>>, _Frames) when Len > ?MAX_FRAME_LEN ->
|
||||
{error, frame_too_large};
|
||||
decode_frames0(<<Len:16, Frame:Len/binary, Rest/binary>>, Frames) ->
|
||||
decode_frames0(Rest, [Frame|Frames]);
|
||||
decode_frames0(Rest, Frames) ->
|
||||
{ok, Rest, lists:reverse(Frames)}.
|
||||
Loading…
x
Reference in New Issue
Block a user