当前位置:网站首页>【斯坦福计网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
通关截图
边栏推荐
- 外包幹了三年,廢了...
- 深度学习花书+机器学习西瓜书电子版我找到了
- [ANSYS] learning experience of APDL finite element analysis
- Blue Bridge Cup Birthday candles (violence)
- Dynamics CRM server deployment - restore database prompt: the database is in use
- Several important steps to light up the display
- How do I get the last part of a string- How to get the last part of a string?
- 95后CV工程师晒出工资单,狠补了这个,真香...
- Kuboard can't send email and nail alarm problem is solved
- IPv4 exercises
猜你喜欢
测试周期被压缩?教你9个方法去应对
Is the test cycle compressed? Teach you 9 ways to deal with it
Robot technology innovation and practice old version outline
Wechat applet full stack development practice Chapter 3 Introduction and use of APIs commonly used in wechat applet development -- 3.10 tabbar component (I) how to open and use the default tabbar comp
Interviewer: what development models do you know?
1142_ SiCp learning notes_ Functions and processes created by functions_ Linear recursion and iteration
Dynamics CRM server deployment - restore database prompt: the database is in use
Outsourcing for four years, abandoned
About some details of final, I have something to say - learn about final CSDN creation clock out from the memory model
After the interview, the interviewer roast in the circle of friends
随机推荐
vus.SSR在asynData函数中请求数据的注意事项
科技云报道:从Robot到Cobot,人机共融正在开创一个时代
抽丝剥茧C语言(高阶)数据的储存+练习
Jenkins远程构建项目超时的问题
I failed in the postgraduate entrance examination and couldn't get into the big factory. I feel like it's over
按键精灵采集学习-矿药采集及跑图
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
How can a 35 year old programmer build a technological moat?
L'externalisation a duré trois ans.
测试周期被压缩?教你9个方法去应对
【Liunx】进程控制和父子进程
Leetcode-226. Invert Binary Tree
在线直播系统源码,使用ValueAnimator实现view放大缩小动画效果
Role of virtual machine
基于Flask搭建个人网站
面试结束后,被面试官在朋友圈吐槽了......
pytorch 参数初始化
微信小程序中的路由跳转
About binary cannot express decimals accurately
leetcode:105. Constructing binary trees from preorder and inorder traversal sequences