在QuicFramer::ProcessDataPacket()中调用ProcessFrameData(),
在ProcessFrameData()调用了ProcessStreamFrame()将包中数据处理完成,
处理完后便会对数据进行上抛。
调用OnStreamFrame(frame),最后会上抛到 QuicStreamSequencerBuffer::OnStreamData()。
根据Quic的发包处理,每个包都会有一个严格递增的packetid,但这并不是丢包后能将重传包排序的标志,而是每个包内容的offset值。
在QuicStreamSequencerBuffer::OnStreamData()中,会有对于这个steam流的一个gap表,这个gap记录了每个缺失的offset的区间。
*bytes_buffered = 0;
QuicStreamOffset offset = starting_offset;
size_t size = data.size();
if (size == 0) {
*error_details = "Received empty stream frame without FIN.";
return QUIC_EMPTY_STREAM_FRAME_NO_FIN;
}
// Find the first gap not ending before |offset|. This gap maybe the gap to
// fill if the arriving frame doesn't overlaps with previous ones.
std::list<Gap>::iterator current_gap = gaps_.begin();
while (current_gap != gaps_.end() && current_gap->end_offset <= offset) {
++current_gap;
} //找到包能填充的丢失区间
DCHECK(current_gap != gaps_.end());
// "duplication": might duplicate with data alread filled,but also might
// overlap across different QuicStringPiece objects already written.
// In both cases, don't write the data,
// and allow the caller of this method to handle the result.
if (offset < current_gap->begin_offset &&
offset + size <= current_gap->begin_offset) {
QUIC_DVLOG(1) << "Duplicated data at offset: " << offset
<< " length: " << size;
return QUIC_NO_ERROR;
}//重传包
if (offset < current_gap->begin_offset &&
offset + size > current_gap->begin_offset) {
// Beginning of new data overlaps data before current gap.
string prefix(data.data(), data.length() < 128 ? data.length() : 128);
*error_details =
QuicStrCat("Beginning of received data overlaps with buffered data.\n",
"New frame range [", offset, ", ", offset + size,
") with first 128 bytes: ", prefix, "\n",
"Currently received frames: ", GapsDebugString(), "\n",
"Current gaps: ", ReceivedFramesDebugString());
return QUIC_OVERLAPPING_STREAM_DATA;
}//意思是说新包的数据覆盖了丢失区域且将其它区域也覆盖了
if (offset + size > current_gap->end_offset) {
// End of new data overlaps with data after current gap.
string prefix(data.data(), data.length() < 128 ? data.length() : 128);
*error_details = QuicStrCat(
"End of received data overlaps with buffered data.\nNew frame range [",
offset, ", ", offset + size, ") with first 128 bytes: ", prefix, "\n",
"Currently received frames: ", ReceivedFramesDebugString(), "\n",
"Current gaps: ", GapsDebugString());
return QUIC_OVERLAPPING_STREAM_DATA;
}//同上
// Write beyond the current range this buffer is covering.
if (offset + size > total_bytes_read_ + max_buffer_capacity_bytes_) {
*error_details = "Received data beyond available range.";
return QUIC_INTERNAL_ERROR;
}//超出缓冲区
if (current_gap->begin_offset != starting_offset &&
current_gap->end_offset != starting_offset + data.length() &&
gaps_.size() >= kMaxNumGapsAllowed) {
// This frame is going to create one more gap which exceeds max number of
// gaps allowed. Stop processing.
*error_details = "Too many gaps created for this stream.";
return QUIC_TOO_MANY_FRAME_GAPS;
}//这个包太大??
当一个流上的包都接收后,会跳转到OnDataAvailable(),在quic-proto中有简单实现例子
void QuicSimpleServerStream::OnDataAvailable() {
while (HasBytesToRead()) {
struct iovec iov;
if (GetReadableRegions(&iov, 1) == 0) {
// No more data to read.
break;
}
QUIC_DVLOG(1) << "Stream " << id() << " processed " << iov.iov_len
<< " bytes.";
body_.append(static_cast<char*>(iov.iov_base), iov.iov_len);
//在这里将会把一个流上传的所有包的数据按顺序添加到body_里,所以当你在client端在流上发送完一个数据时可以在这里将数据打印出来
if (content_length_ >= 0 &&
body_.size() > static_cast<uint64_t>(content_length_)) {
QUIC_DVLOG(1) << "Body size (" << body_.size() << ") > content length ("
<< content_length_ << ").";
SendErrorResponse();
return;
}
MarkConsumed(iov.iov_len);
}
if (!sequencer()->IsClosed()) {
sequencer()->SetUnblocked();
return;
}
// If the sequencer is closed, then all the body, including the fin, has been
// consumed.
OnFinRead();
if (write_side_closed() || fin_buffered()) {
return;
}
SendResponse(); //因为quic-proto的例子是请求网页数据,server端会给予返回,可以根据这个函数查看怎么发送一个完整的数据
}
以上为初学者理解,仅供参考

654

被折叠的 条评论
为什么被折叠?



