Why can a stream continue to receive data frames after receiving the END_STREAM flag (detailed explanation of HTTP/2 stream status changes)

First, attach the answer:
When wireshark captured the packet, I found that a data frame contained the END_STREAM flag, but the stream was still not over, and the data frame was still being transmitted .This is because the state of the stream has changed from open to half_closed(local). In this state, the stream can only send Window_Updata, Priority, and RST_Stream frames, and can receive any frame.

Flags of the frame in frame (flags)

A frame is the smallest data transmission unit in HTTP/2 communication. The definition of a frame is as follows:

+-----------------------------------------------+
|                 Length (24)                   |
+---------------+---------------+---------------+
|   Type (8)    |   Flags (8)   |
+-+-------------+---------------+-------------------------------+
|R|                 Stream Identifier (31)                      |
+=+=============================================================+
|                   Frame Payload (0...)                      ...
+---------------------------------------------------------------+

Flags is the flag bit of the frame, such as END_HEADERS is 0x04 (marking the end of the header data), END_STREAM is 0x01 (marking the end of the stream).

Attach a simple transition process of
stream State transition of Stream

                             +--------+
                     send PP |        | recv PP
                    ,--------|  idle  |--------.
                   /         |        |         \
                  v          +--------+          v
           +----------+          |           +----------+
           |          |          | send H /  |          |
    ,------| reserved |          | recv H    | reserved |------.
    |      | (local)  |          |           | (remote) |      |
    |      +----------+          v           +----------+      |
    |          |             +--------+             |          |
    |          |     recv ES |        | send ES     |          |
    |   send H |     ,-------|  open  |-------.     | recv H   |
    |          |    /        |        |        \    |          |
    |          v   v         +--------+         v   v          |
    |      +----------+          |           +----------+      |
    |      |   half   |          |           |   half   |      |
    |      |  closed  |          | send R /  |  closed  |      |
    |      | (remote) |          | recv R    | (local)  |      |
    |      +----------+          |           +----------+      |
    |           |                |                 |           |
    |           | send ES /      |       recv ES / |           |
    |           | send R /       v        send R / |           |
    |           | recv R     +--------+   recv R   |           |
    | send R /  `----------->|        |<-----------'  send R / |
    | recv R                 | closed |               recv R   |
    `----------------------->|        |<----------------------'
                             +--------+
       send:   endpoint sends this frame
       recv:   endpoint receives this frame
       H:  HEADERS frame (with implied CONTINUATIONs)
       PP: PUSH_PROMISE frame (with implied CONTINUATIONs)
       ES: END_STREAM flag
       R:  RST_STREAM frame

The difference between local and remote in half closed (local/remote)
half closed (local/remote)
status half closed (local) and half closed (remote) is completely based on the perspective of each end. For both ends of the same stream, if one end considers the status of the stream to be half closed (local), then the other end can only consider the status of the stream to be half closed (remote).
A stream in the half closed (local) state can only be used to send WINDOW_UPDATE, PRIORITY and RST_STREAM frames, but it can be used to receive any type of frame. Correspondingly, a stream in the half closed (remote) state can only be used to receive WINDOW_UPDATE, PRIORITY and RST_STREAM frames, but it can be used to send any type of frame.

Guess you like

Origin blog.csdn.net/weixin_45022086/article/details/108750765