当前位置:网站首页>[Stanford Jiwang cs144 project] lab3: tcpsender
[Stanford Jiwang cs144 project] lab3: tcpsender
2022-07-07 07:43:00 【Altair_ alpha】
In this section TCP The sender in the protocol TCPSender The implementation of the .Sender Have an input ByteStream, On behalf of the data provided by the user to be sent , and Sender Be responsible for assembling it into TCP Packet and send it out . So called sending , That is to put the data package push To a queue _segments_out Then you can , The next section realizes TCPConnection class ( That is to say Sender and Receiver Owner ) It will be responsible for taking packets from the queue and actually sending them .
Except for the guarantee TCPSegment Data in the 、 Serial number and SYN,FIN Wait until the logo is set correctly ,Sender There are two main issues to consider . First, the receiving window ,Receiver The amount of data that can be received at one time is limited , Will pass Header in Window Size Field to Sender Dynamic feedback of this information .Sender It should be ensured that ( That is, it has been sent and has not been confirmed to receive ) The amount of data is less than or equal to this window .
Second, data retransmission , Because the data packet may be lost during transmission ,Sender You cannot discard a packet immediately after sending it , Instead, it is placed in the temporary storage area ( be called outstanding data), If you haven't received it within a period of time Receiver Confirmation signal of ( adopt ackno) You need to retransmit . The handout stipulates that it will be true TCP A series of rules after the agreement is slightly simplified are as follows :
- Perception of time . In order to ensure the certainty of program testing ,Sender The implementation does not actively call any actual time API, Instead, it passively invokes its
tickThe function perceives the passage of time , The parameter of this function is from the last calltickThe number of milliseconds elapsed after . - The concept of timer . There needs to be a Timer, It can be activated , Triggered after a set time interval , It can also be stopped manually . Because the perception of time is passive , therefore Timer It can only be in
tickFunction . - Sender Accept an initial Retransmission timeout (retransmission timeout, RTO) Parameters , This initial parameter is fixed , At the same time, there is a current RTO Parameters . Every time a packet is sent , If Timer Not activated , Start and make it current RTO Triggered in milliseconds . When all data in the staging area is ack when , stop it Timer.
- When Timer stay
tickWhen triggered in , Will not be completely ack Of One of the earliest ( That is, the one with the smallest serial number ) Temporary packet retransmission . meanwhile , If the window size is not 0, Record the number of consecutive retransmissions , This information will be implemented in the next section TCPConnection Used to determine whether to end the connection , and Make current RTO Double ( Index retreat ). Then according to the current RTO( Probably just updated ) start-up Timer. - When receiving a request for newly sent data ack when , Will the current RTO Reset to initial RTO, And set the number of consecutive retransmissions to zero . If the staging area is not empty , start-up Timer.
Implementation , Mainly Timer + Three main functions . Refer to the code of many students on the Internet Timer The function is put in Sender In the class implementation , I still have a separate class here as follows :
// Helper class to determine whether a given timeout has reached (i.e., expired) since started.
// It won't emit any signal but provide accessor for caller to check its state
// Also the class won't call any system time function but rely on its update() called to
// know time elapsed and whether timeout is reached.
class Timer {
public:
// start the timer with given timeout.
// call start() on a started timer acts like reset() called first
void start(unsigned int timeout);
// update the timer with info of time elapsed since start/last update
void update(unsigned int time_elapsed);
// reset(stop) the timer
void reset();
// check whether the timer is active
bool active() const {
return _active; }
// check whether the timer has timed out (if the timer is inactive, return value is false)
bool expired() const {
return _active && _expired; }
private:
bool _active{
false};
bool _expired{
false};
unsigned int _current_time{
0};
unsigned int _timeout{
0};
};
One of the main functions : void ack_received(const WrappingInt32 ackno, const uint16_t window_size). The window size is determined by the members of a class _window_size Record updates , This parameter is used in the following sending function .ackno the unwrap Then compare with the packet number in the temporary storage area one by one , Remove the completely confirmed packets ( Note that the packet number in the staging area can be used to order from small to large ). If you can remove , Reset by rule RTO And retransmission count . If the staging area is empty after removal , take Timer stop it . Because the temporary storage area may be vacated , Last call fill_window( See below ) Try sending a new packet . The code is as follows :
void TCPSender::ack_received(const WrappingInt32 ackno, const uint16_t window_size) {
_window_size = window_size;
// use next seqno as checkpoint
uint64_t ack_seqno = unwrap(ackno, _isn, _next_seqno);
// it's impossible that ackno > _next_seqno, because that byte hasn't been sent yet!
if (ack_seqno > _next_seqno) {
return;
}
// remove completely ack-ed segments from the retransmission buffer
// because the segment in retrans buffer is ordered by seqno,
// it's ok to break once current seg can't be erased (subsequent seg has larger seqno)
for (auto it = _retrans_buf.begin(); it != _retrans_buf.end();) {
if (unwrap((*it).header().seqno, _isn, _next_seqno) + (*it).length_in_sequence_space() <= ack_seqno) {
it = _retrans_buf.erase(it);
_retrans_timeout = _initial_retransmission_timeout;
_timer.start(_retrans_timeout);
_consec_retrans_count = 0;
} else
break;
}
// stop the timer if retransmission buffer is clear
if (_retrans_buf.empty())
_timer.reset();
// refill the window
fill_window();
}
The second of the main functions :void tick(const size_t ms_since_last_tick). If Timer Started , Then update the time according to the parameters , Then check whether it triggers . If the trigger , Then retransmit according to the rules , Increase retransmission count , send RTO Double , And restart Timer. The code is as follows :
void TCPSender::tick(const size_t ms_since_last_tick) {
if (_timer.active())
_timer.update(ms_since_last_tick);
if (_timer.expired()) {
_segments_out.emplace(_retrans_buf.front());
if (_window_size > 0) {
_consec_retrans_count++;
_retrans_timeout *= 2;
}
_timer.start(_retrans_timeout);
}
}
The third of the main functions :void fill_window(). That is, the one mentioned at the beginning “ send data 、 Serial number and SYN,FIN Wait for the packet with the correct identification setting ”. Generally speaking, the process is : Determine whether the window is not filled → If it is not filled , Make one TCPSegment, Specifically, it is divided into judgment and release SIN identification , Put the data , Judge release FIN Identify three steps → take TCPSegment Add to _segments_out And staging area , Update the serial number and remaining space . Cycle until the window is filled . See the following source file for details , Don't paste it .
Full code link :
tcp_sender.hh
tcp_sender.cc
Screenshot of customs clearance 
边栏推荐
- gslx680触摸屏驱动源码码分析(gslX680.c)
- Talk about seven ways to realize asynchronous programming
- 深度学习花书+机器学习西瓜书电子版我找到了
- Six methods of flattening arrays with JS
- 【数学笔记】弧度
- After 95, the CV engineer posted the payroll and made up this. It's really fragrant
- 身边35岁程序员如何建立起技术护城河?
- 微信小程序中的路由跳转
- 外包干了四年,废了...
- Model application of time series analysis - stock price prediction
猜你喜欢

Music | cat and mouse -- classic not only plot

【斯坦福计网CS144项目】Lab4: TCPConnection

2022-07-06: will the following go language codes be panic? A: Meeting; B: No. package main import “C“ func main() { var ch chan struct

95后CV工程师晒出工资单,狠补了这个,真香...

三、高质量编程与性能调优实战 青训营笔记

Wechat applet full stack development practice Chapter 3 Introduction and use of APIs commonly used in wechat applet development -- 3.9 introduction to network interface (IX) extending the request3 met

抽丝剥茧C语言(高阶)指针进阶练习

My ideal software tester development status

1090: integer power (multi instance test)

UWB learning 1
随机推荐
Flutter riverpod is comprehensively and deeply analyzed. Why is it officially recommended?
07_ Handout on the essence and practical skills of text measurement and geometric transformation
在线直播系统源码,使用ValueAnimator实现view放大缩小动画效果
pytorch 参数初始化
Interviewer: what development models do you know?
【Unity】物体做圆周运动的几个思路
UWB learning 1
【云原生】内存数据库如何发挥内存优势
1142_ SiCp learning notes_ Functions and processes created by functions_ Linear recursion and iteration
科技云报道:从Robot到Cobot,人机共融正在开创一个时代
After the interview, the interviewer roast in the circle of friends
IO stream file
Leetcode-226. Invert Binary Tree
1、 Go knowledge check and remedy + practical course notes youth training camp notes
Six methods of flattening arrays with JS
Solve could not find or load the QT platform plugin "xcb" in "
Resource create package method
1140_ SiCp learning notes_ Use Newton's method to solve the square root
How to * * labelimg
电商常规问题part1