读数据
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;
}