posix_quic-master接受收据

本文深入探讨了QUIC协议在POSIX环境下的数据读取过程,详细跟踪了QuicRead()和QuicReadv()函数,尤其是对Readv()函数的多次调用和跟进分析,揭示了QUIC在接收数据时的底层机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

读数据

res = QuicRead(fd, buf, sizeof(buf));//读事件

跟踪一下这个QuicRead()函数

ssize_t QuicRead(QuicStream stream, void* data, size_t length)
{
    struct iovec iov;
    iov.iov_base = data;
    iov.iov_len = length;
    return QuicReadv(stream, &iov, 1);
}

跟踪这个QuicReadv()函数

ssize_t QuicRead(QuicStream stream, void* data, size_t length)
{
    struct iovec iov;
    iov.iov_base = data;
    iov.iov_len = length;
    return QuicReadv(stream, &iov, 1);
}

//跟进这个QuicReadv()函数

ssize_t QuicReadv(QuicStream stream, const struct iovec* iov, int iov_count)
{
    auto streamPtr = EntryBase::GetFdManager().Get(stream);
    if (!streamPtr || streamPtr->Category() != EntryCategory::Stream) {
        DebugPrint(dbg_api, "stream = %d, return = -1, errno = EBADF", stream);
        errno = EBADF;
        return -1;
    }

    ssize_t res = ((QuicStreamEntry*)streamPtr.get())->Readv(iov, iov_count);
    DebugPrint(dbg_api, "stream = %d, return = %ld, errno = %d", stream, res, errno);
    return res;
}

//跟进这个Readv()函数

ssize_t QuicStreamEntry::Readv(const struct iovec* iov, size_t iov_count)
{
    if (Error()) {
        errno = Error();
        return -1;
    }

    if (finRead_) {
        errno = 0;
        return 0;
    }

    auto stream = GetQuartcStream();
    if (!stream) {
        errno = EBADF;
        return -1;
    }

    int res = stream->Readv(iov, iov_count);
    if (res == 0) {
        if (Error()) {
            errno = Error();
            return -1;
        }

        if (finRead_) {
            errno = 0;
            return 0;
        }

        errno = EAGAIN;
        return -1;
    }

    errno = 0;
    return res;
}

//跟进这个Readv()函数

int QuartcStream::Readv(const struct iovec* iov, size_t iov_len) {
  int res = sequencer()->Readv(iov, iov_len);
  if (sequencer()->IsClosed())
    OnFinRead();
  return res;
}

//Readv()函数

int QuicStreamSequencer::Readv(const struct iovec* iov, size_t iov_len) {
  DCHECK(!blocked_);
  QuicString error_details;
  size_t bytes_read;
  QuicErrorCode read_error =
      buffered_frames_.Readv(iov, iov_len, &bytes_read, &error_details);
  if (read_error != QUIC_NO_ERROR) {
    QuicString details =
        QuicStrCat("Stream ", stream_->id(), ": ", error_details);
    stream_->CloseConnectionWithDetails(read_error, details);
    return static_cast<int>(bytes_read);
  }

  stream_->AddBytesConsumed(bytes_read);
  return static_cast<int>(bytes_read);
}

//跟进这个Readv函数

QuicErrorCode QuicStreamSequencerBuffer::Readv(const iovec* dest_iov,
                                               size_t dest_count,
                                               size_t* bytes_read,
                                               QuicString* error_details) {
//接受对象是否损坏
  CHECK_EQ(destruction_indicator_, 123456) << "This object has been destructed";

  *bytes_read = 0;
  for (size_t i = 0; i < dest_count && ReadableBytes() > 0; ++i) {
    char* dest = reinterpret_cast<char*>(dest_iov[i].iov_base);
    CHECK_NE(dest, nullptr);
    size_t dest_remaining = dest_iov[i].iov_len;
    while (dest_remaining > 0 && ReadableBytes() > 0) {
      size_t block_idx = NextBlockToRead();
      size_t start_offset_in_block = ReadOffset();
      size_t block_capacity = GetBlockCapacity(block_idx);
      size_t bytes_available_in_block = std::min<size_t>(
          ReadableBytes(), block_capacity - start_offset_in_block);
      size_t bytes_to_copy =
          std::min<size_t>(bytes_available_in_block, dest_remaining);
      DCHECK_GT(bytes_to_copy, 0UL);
      if (blocks_[block_idx] == nullptr || dest == nullptr) {
        *error_details = QuicStrCat(
            "QuicStreamSequencerBuffer error:"
            " Readv() dest == nullptr: ",
            (dest == nullptr), " blocks_[", block_idx,
            "] == nullptr: ", (blocks_[block_idx] == nullptr),
            " Gaps: ", GapsDebugString(),
            " Remaining frames: ", ReceivedFramesDebugString(),
            " total_bytes_read_ = ", total_bytes_read_);
        return QUIC_STREAM_SEQUENCER_INVALID_STATE;
      }
      memcpy(dest, blocks_[block_idx]->buffer + start_offset_in_block,
             bytes_to_copy);
      dest += bytes_to_copy;
      dest_remaining -= bytes_to_copy;
      num_bytes_buffered_ -= bytes_to_copy;
      total_bytes_read_ += bytes_to_copy;
      *bytes_read += bytes_to_copy;

      // Retire the block if all the data is read out and no other data is
      // stored in this block.
      // In case of failing to retire a block which is ready to retire, return
      // immediately.
      if (bytes_to_copy == bytes_available_in_block) {
        bool retire_successfully = RetireBlockIfEmpty(block_idx);
        if (!retire_successfully) {
          *error_details = QuicStrCat(
              "QuicStreamSequencerBuffer error: fail to retire block ",
              block_idx,
              " as the block is already released, total_bytes_read_ = ",
              total_bytes_read_, " Gaps: ", GapsDebugString());
          return QUIC_STREAM_SEQUENCER_INVALID_STATE;
        }
      }
    }
  }

  if (*bytes_read > 0) {
    UpdateFrameArrivalMap(total_bytes_read_);
  }
  return QUIC_NO_ERROR;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值