赞
踩
在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端会给予返回,可以根据这个函数查看怎么发送一个完整的数据 }
以上为初学者理解,仅供参考
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。