pub struct RecvStream { /* private fields */ }展开描述
仅可用于接收数据的流
在以下情况之外,析构时会隐式调用 stop(0):
§取消
当某个 read 方法的 future 在尚未就绪时被丢弃,但不会造成流数据丢失时,称该方法是可安全取消的(cancel-safe)。只要有任意的进展就能立即成功的方法属于可安全取消的;而那些内部可能需要执行多次读才能成功的方法则不属于。每个 read 方法的文档都会注明它是否可安全取消。
§常见问题
§在本地打开的流上始终收不到数据
对端在真正被用来发送数据(无论是它本身还是与它编号相同或更大的某条流)之前,并不会被通知该流的存在。如果一条双向流是在本地打开但始终未被用于发送,那么对端可能永远看不到这条流。应用协议应始终把“将先在该流上发送数据”的那一端安排为打开该流的一方。
§在远端打开的流上始终收不到数据
请确认你正在接收的流与服务器正在发送数据的流是同一条,例如记录每条流的 id。流被接受的顺序与它们被创建的顺序完全一致,即按 StreamId 升序排列。例如,即便发送方先在双向流 1 上传输数据,接收端从 Connection::accept_bi 中拿到的第一条流仍是双向流 0。
实现§
源代码§impl RecvStream
impl RecvStream
源代码pub async fn read(&mut self, buf: &mut [u8]) -> Result<Option<usize>, ReadError>
pub async fn read(&mut self, buf: &mut [u8]) -> Result<Option<usize>, ReadError>
从流中连续读取数据。
成功时返回已读入 buf 的字节数;若流已结束,则返回 None。
此操作是取消安全的。
源代码pub async fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), ReadExactError>
pub async fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), ReadExactError>
从流中连续读取指定数量的字节。
详见 read()。此操作不是取消安全的。
源代码pub fn poll_read(
&mut self,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<Result<usize, ReadError>>
pub fn poll_read( &mut self, cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll<Result<usize, ReadError>>
尝试从流中读取数据到所提供的缓冲区
成功时返回 Poll::Ready(Ok(num_bytes_read)),并将数据放入 buf。如果返回读取到的字节数为零(且 buf 长度非零),表示远端已经 finish 了流,且本地端已读取完所有字节。
如果没有可读数据,则返回 Poll::Pending,并安排当前任务(经由 cx.waker())在流变为可读或被关闭时收到通知。
源代码pub fn poll_read_buf(
&mut self,
cx: &mut Context<'_>,
buf: &mut ReadBuf<'_>,
) -> Poll<Result<(), ReadError>>
pub fn poll_read_buf( &mut self, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<Result<(), ReadError>>
尝试从流中读取数据到所提供的缓冲区(缓冲区可能未初始化)
成功时返回 Poll::Ready(Ok(())),并将数据放入 buf 的未填充区域。如果未向 buf 写入任何字节(且 buf.remaining() 非零),表示远端已经 finish 了流,且本地端已读取完所有字节。
如果没有可读数据,则返回 Poll::Pending,并安排当前任务(经由 cx.waker())在流变为可读或被关闭时收到通知。
源代码pub async fn read_chunk(
&mut self,
max_length: usize,
ordered: bool,
) -> Result<Option<Chunk>, ReadError>
pub async fn read_chunk( &mut self, max_length: usize, ordered: bool, ) -> Result<Option<Chunk>, ReadError>
读取下一段数据
若流已结束,返回 None;否则返回一段数据及其在流中的偏移。若 ordered 为 true,数据块的偏移紧跟在 read() 或 read_chunk() 上次返回的数据之后;若为 false,各段可能按任意顺序到达,调用方可借助 Chunk 的 offset 字段自行确定顺序。无序读取更不易在单个流中产生队头阻塞,但应用需自行管理原始数据的重组。
因为无需拷贝,所以略高于 read 的效率。数据块的边界与对端的写入不对应,因此不能用作分帧。
此操作是取消安全的。
源代码pub async fn read_chunks(
&mut self,
bufs: &mut [Bytes],
) -> Result<Option<usize>, ReadError>
pub async fn read_chunks( &mut self, bufs: &mut [Bytes], ) -> Result<Option<usize>, ReadError>
读取接下来若干段数据
使用紧接在 read 或 read_chunk 上次返回数据之后的数据段填满 bufs;若流已结束则返回 None。
因为无需拷贝,所以略高于 read 的效率。数据块的边界与对端的写入不对应,因此不能用作分帧。
此操作是取消安全的。
源代码pub async fn read_to_end(
&mut self,
size_limit: usize,
) -> Result<Vec<u8>, ReadToEndError>
pub async fn read_to_end( &mut self, size_limit: usize, ) -> Result<Vec<u8>, ReadToEndError>
将所有剩余数据读取到一个缓冲区的便捷方法
若读取字节数超过 size_limit,则返回 ReadToEndError::TooLong,并丢弃已读取的全部数据。该方法使用无序读取,比使用 AsyncRead 接口更高效。size_limit 用于限制最坏情况下的内存占用。
若此前已做过无序读取,结果缓冲区中可能出现包含任意数据的间隙。
此操作不是取消安全的。
源代码pub fn stop(&mut self, error_code: VarInt) -> Result<(), ClosedStream>
pub fn stop(&mut self, error_code: VarInt) -> Result<(), ClosedStream>
停止接受数据
丢弃尚未读取的数据,并通知对端停止发送。停止之后,任何再对该流进行的操作都将返回 ClosedStream 错误。
源代码pub fn is_0rtt(&self) -> bool
pub fn is_0rtt(&self) -> bool
检查该流是否在 0-RTT 期间被打开。
若为 0-RTT 流,则任何非幂等请求在应用层都应视为存在危险,因为读取到的数据可能遭受重放攻击。