msquic/docs/api/StreamSend.md

5.1 KiB

StreamSend function

Queues app data to be sent on a stream.

Syntax

typedef
_IRQL_requires_max_(DISPATCH_LEVEL)
QUIC_STATUS
(QUIC_API * QUIC_STREAM_SEND_FN)(
    _In_ _Pre_defensive_ HQUIC Stream,
    _In_reads_(BufferCount) _Pre_defensive_
        const QUIC_BUFFER* const Buffers,
    _In_ uint32_t BufferCount,
    _In_ QUIC_SEND_FLAGS Flags,
    _In_opt_ void* ClientSendContext
    );

Parameters

Stream

The valid handle to an open stream object.

Buffers

An array of QUIC_BUFFER structs that each contain a pointer and length to app data to send on the stream. This may be NULL only if BufferCount is zero.

BufferCount

The number of QUIC_BUFFER structs in the Buffers array. This may be zero.

Flags

The set of flags the controls the behavior of StreamSend:

Value Meaning
QUIC_SEND_FLAG_NONE
0
No special behavior. Data is not allowed in 0-RTT by default.
QUIC_SEND_FLAG_ALLOW_0_RTT
1
Indicates that the data is allowed to be sent in 0-RTT (if available). Makes no guarantee the data will be sent in 0-RTT. Additionally, even if 0-RTT keys are available the data may end up being sent in 1-RTT for multiple reasons.
QUIC_SEND_FLAG_START
2
Indicates that the stream should asynchronously start (equivalent to calling StreamStart).
QUIC_SEND_FLAG_FIN
4
Indicates the the stream send is the last or final data to be sent on the stream and should be gracefully shutdown (equivalent to calling StreamShutdown with the QUIC_STREAM_SHUTDOWN_FLAG_GRACEFUL flag).
QUIC_SEND_FLAG_DGRAM_PRIORITY
8
Unused and ignored for StreamSend
QUIC_SEND_FLAG_DELAY_SEND
16
Provides a hint to MsQuic to indicate the data does not need to be sent immediately, likely because more is soon to follow.

ClientSendContext

The app context pointer (possibly null) to be associated with the send.

Return Value

The function returns a QUIC_STATUS. The app may use QUIC_FAILED or QUIC_SUCCEEDED to determine if the function failed or succeeded.

Remarks

This function is used to queue data on a stream to be sent. The function itself is non-blocking and simply queues the data and returns. The app may pass zero or more buffers of data that will be sent on the stream in the order they are passed. The buffers (both the QUIC_BUFFERs and the memory they reference) are "owned" by MsQuic (and must not be modified by the app) until MsQuic indicates the QUIC_STREAM_EVENT_SEND_COMPLETE event for the send.

By default, data queued via StreamSend is not allowed to be sent in 0-RTT packets, but the app may override this by passing the QUIC_SEND_FLAG_ALLOW_0_RTT flag. This flag indicates that the data is acceptable to be sent in a 0-RTT packet, but does not guarantee that data will be sent in 0-RTT. There are several reasons it may not be sent in 0-RTT:

  • The 0-RTT keys were not available.
  • The server rejected 0-RTT data for some reason.
  • Too much data was queued and it couldn't all fit.
  • The data was sent, but eventually found to have been lost and retransmitted in a 1-RTT packet.

Some apps may open and send on many different streams at a very high rate. In these scenarios, having to call StreamStart and StreamShutdown for every stream adds unwanted performance overhead. In order to optimize these scenarios, StreamStart supports the QUIC_SEND_FLAG_START and QUIC_SEND_FLAG_FIN flags, which allows the app to do something like this:

HQUIC Stream;
MsQuic->StreamOpen(
    Connection,
    QUIC_STREAM_OPEN_FLAG_UNIDIRECTIONAL,
    AppHandler,
    AppContext,
    &Stream);
MsQuic->StreamSend(
    Stream,
    &AppData,
    1,
    QUIC_SEND_FLAG_START | QUIC_SEND_FLAG_FIN,
    AppSendContext);

Note For the sake of brevity, error handling and clean up has been omitted.

This example opens a new unidirectional stream, and queues a send that starts the stream, sends some app data and gracefully closes the stream.

In some scenarios, the app may know that additional data (possibly on a different stream) will soon be queued after the current call to StreamSend. In these cases it may be helpful for the app to pass the QUIC_SEND_FLAG_DELAY_SEND flag to hint that MsQuic should wait for more data before flushing the connection-wide send queue. Note that anything else on the connection might still end up triggering the send to flush. The app may call StreamSend (on any stream) with a null/empty buffer with QUIC_SEND_FLAG_DELAY_SEND unset to force a flush.

Important: Data queued via StreamSend with the QUIC_SEND_FLAG_DELAY_SEND flag is not guaranteed to be sent until a subsequent StreamSend call on any stream is performed without the QUIC_SEND_FLAG_DELAY_SEND flag.

For additional information on sending on streams see here.

See Also

StreamOpen
StreamClose
StreamStart
StreamShutdown
StreamReceiveComplete
StreamReceiveSetEnabled