decode frames

This commit is contained in:
anlicheng 2026-02-13 13:40:24 +08:00
parent 2a8ead5f01
commit 2ff9cf51ce
2 changed files with 52 additions and 6 deletions

View File

@ -19,8 +19,27 @@ start() ->
do_start() -> do_start() ->
Port = 1365, Port = 1365,
{ok, Conn} = quicer:connect("localhost", Port, [{alpn, ["punchnet/1.0"]}, {verify, none}], 5000), {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, Stm} = quicer:start_stream(Conn, []),
{ok, 4} = quicer:send(Stm, <<"ping">>), receive
logger:debug("[quic_client] client send success"), {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, receive {quic, <<"pong">>, Stm, _Props} -> ok end,
ok = quicer:close_connection(Conn). ok = quicer:close_connection(Conn).

View File

@ -11,6 +11,8 @@
-behaviour(gen_statem). -behaviour(gen_statem).
-define(MAX_FRAME_LEN, 16384).
%% API %% API
-export([start_link/1]). -export([start_link/1]).
@ -19,7 +21,9 @@
-record(state, { -record(state, {
conn :: quicer:connection_handle(), 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} {stop, Reason, State}
end; end;
%% quicer相关的信息 handle_event(info, {frame, Frame}, _StateName, State = #state{}) ->
handle_event(info, {quic, Msg, Stream, _Props}, _StateName, State = #state{stream_handle = Stream}) -> logger:debug("[sdlan_quic_channel] get frame: ~p", [Frame]),
logger:debug("[sdlan_quic_channel] get message: ~p", [Msg]),
{keep_state, State}; {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}) -> handle_event(info, {quic_closed, Stream, _Props}, _StateName, State = #state{conn = Conn, stream_handle = Stream}) ->
quicer:close_connection(Conn), quicer:close_connection(Conn),
{stop, connection_closed, State}; {stop, connection_closed, State};
@ -106,3 +120,16 @@ code_change(_OldVsn, StateName, State = #state{}, _Extra) ->
%%%=================================================================== %%%===================================================================
%%% Internal functions %%% 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)}.