当前位置:网站首页>【斯坦福计网CS144项目】Lab4: TCPConnection
【斯坦福计网CS144项目】Lab4: TCPConnection
2022-07-07 04:13:00 【Altair_alpha】
在实现了接收端的 TCPReceiver 类和发送端的 TCPSender 类后,本节实验实现掌管这两个类,向用户提供一个完整的 TCP 连接抽象的 TCPConnection 类。正如讲义标题所写,完成本节的实验后,我们是真正攀登上了一个高峰(summit),也是完成了本门课程最重要精华的部分。
事前提醒,本节的测试量非常大,其中会用你的 TCP 实现与 Linux 的 TCP 实现进行各种条件的交互,之前的 Sender 和 Receiver 类在实现上如果有潜在问题也都会被暴露出来。所以,如果你在尝试自己实现,请做好耐心 Debug 的准备。虽然直接看其它人的 blog 可能感觉逻辑都很自然,但自己动手是完全不一样的。我当时也花了 2 整天左右才通过了所有测试。

TCP 是全双工通信,即双方可以同时发送/接收信息。如图所示,TCPConnection 类应该是架设在 TCPSender 和 TCPReceiver 之上的。当 Sender 需要发送数据包时,从其发送队列 _segments_out 中取出数据包并实际发送出去;当接收到数据包时,做必要处理后交给 Receiver 处理。另外,之前我们一直没有关注 TCP 包头中很重要的一个标识 RST,这也是 TCPConnection 要负责的,即异常状态的处理。最后,TCPConnection 还应该处理好连接的终止,包括正常终止和异常终止两种情况。以下我们分别来讨论这几个问题以及实现思路。
注:这里发送的实现其实还是将数据包从 Sender 取出转存到 TCPConnection 的一个发送队列中,之后会由更上层的所有者实际负责发送
接收数据包
对应函数:void segment_received(const TCPSegment &seg)。
- 如果 RST 标识存在,立刻将出入向的数据流均设置为错误状态,并结束连接。可以将结束连接提炼为一个
_shutdown(bool)函数,参数代表是正常还是异常结束,这里即为异常结束。否则: - 将数据包交给 Receiver 处理,即调用 Receiver 的
segment_received。 - 如果 ACK 标识存在,通知 Sender 其关注的信息(ackno 和 window size),即调用 Sender 的
ack_received。 - 如果数据包有序列号,至少保证有一个回复数据包被回复,即应该检查 Sender 的发送队列是否为空,如果为空则造一个空包。
- “keep-alive” 包的回复:对方可能发送一个包含无效序列号的数据包以探测连接是否仍有效,此时应回复一个空包。实现方法讲义已给出。
发送数据包
- Sender 构造的待发送包还不完整,ackno 和 window size 信息应该由 Receiver 给出(如果存在 ackno,还要设置 ACK 标识)。
- 任何时刻 Sender 向发送队列中 push 了一个包,TCPConnection 都应该立刻将其发送。因此,TCPConnection 应该实现一个清空 Sender 队列,填充 Receiver 信息并发送的函数(我的实现中命名为
_clear_sendbuf),在任何可能使 Sender 发送数据包的语句之后都调用该函数。
时间的感知
与 Sender 相同,TCPConnection 也是通过其 tick 函数被调用而被动的感知时间的经过。当 tick 被调用时:
- 使 Sender
tick。 - 如果 Sender 的重传次数超过某阈值,终止连接并发送一个带 RST 标识的空包。终止连接与上面收到对方 RST 包的处理一样,即调用
_shutdown(false)。 - 如果时机合适,正常结束连接(见下一节)。
连接的终止
以上已经讨论过连接异常终止的两种情况,即主动检测到重传次数过多或被动收到对方的 RST 包,这里主要讨论的是连接的正常终止。
理论上来说,通过不可信连接通信的双方无法绝对确保达成共识(参考:两军问题),不过 TCP 设计了一种可信度较高的方案。以一方(local 方)的观点来看,至少有四件事成立才能正常终止连接:
- 入向流(inbound)的数据已经完全接收重组完毕并结束。
- 出向流(outbound)的数据已经完全发送并且带 FIN 标识的包也已被发送。
- 出向流被对方完全确认接收。
- local 方相信 remote 方能够满足第三条。这是最难解决的,因为 TCP 不会对 ack 信息做 ack,否则就没有尽头了。于是有两种选项:
- 延迟关闭(lingering)。当前三条都成立且经过了一定时间后 local 方都没有收到 remote 方重传任何数据,则 local 方能够比较确信双方的所有数据已经正确传输完毕并关闭连接。具体来说,这个时间设置为初始重传超时的 10 倍。
- 被动关闭。如果入向流的结束早于出向流含 FIN 标识包的发送,则 local 方在出向流也结束后立刻关闭连接。其中的原因讲义中给出了解释,这里就不展开了。
测试
除了运行自动化测试外,本节完成后已经可以用两个自己的 TCP 端进行通信,以及用自己的 TCP 代替 Lab0 中的 TCPSocket 与真实的服务器进行通信,还可以测试自己 TCP 实现的性能,操作方法讲义中都有描述。
完整代码链接:
tcp_connection.hh
tcp_connection.cc
通关截图 


边栏推荐
- After 95, Alibaba P7 published the payroll: it's really fragrant to make up this
- pytorch 参数初始化
- Stockage et pratique des données en langage C (haut niveau)
- 海思芯片(hi3516dv300)uboot镜像生成过程详解
- Interviewer: what development models do you know?
- PostgreSQL source code (59) analysis of transaction ID allocation and overflow judgment methods
- MySQL service is missing from computer service
- UWB learning 1
- leetcode:105. 从前序与中序遍历序列构造二叉树
- 智联+影音,AITO问界M7想干翻的不止理想One
猜你喜欢
随机推荐
The annual salary of general test is 15W, and the annual salary of test and development is 30w+. What is the difference between the two?
测试周期被压缩?教你9个方法去应对
Stockage et pratique des données en langage C (haut niveau)
2022-07-06:以下go语言代码是否会panic?A:会;B:不会。 package main import “C“ func main() { var ch chan struct
Detailed explanation of transform origin attribute
Advanced level of C language (high level) pointer
智联+影音,AITO问界M7想干翻的不止理想One
leetcode:105. 从前序与中序遍历序列构造二叉树
Project practice five fitting straight lines to obtain the center line
After 95, the CV engineer posted the payroll and made up this. It's really fragrant
【云原生】内存数据库如何发挥内存优势
About some details of final, I have something to say - learn about final CSDN creation clock out from the memory model
vus. Precautions for SSR requesting data in asyndata function
L'étape avancée du pointeur de langage C (haut de gamme) pour l'enroulement des cocons
KBU1510-ASEMI电源专用15A整流桥KBU1510
Build personal website based on flask
ROS2规划系统plansys2简单的例子
Summary of customer value model (RFM) technology for data analysis
Model application of time series analysis - stock price prediction
按键精灵脚本学习-关于天猫抢红包
![[2022 ACTF]web题目复现](/img/e4/ab9a1771489d751ee73a79f151d374.png)


![[Linux] process control and parent-child processes](/img/4c/89f87ee97f0f8e9033b9f0ef46a80d.png)





