自顶向下 | 带你遨游运输层
学习导图:
一.运输层概述
运输层为运行在不同主机上的应用程序之间提供逻辑通信
应用报文加上运输层首部形成运输层报文段,报文段通过网络层被封装成网络层分组(数据报)向目的地发送
Q1:运输层和网络层的关系
运输层:运行在不同主机上的应用程序之间提供逻辑通信
网络层:提供主机之间的通信
举个例子来说明两者关系:
有两个家庭,一家位于广州,一家位于北京,每家有 3个孩子。这两个家庭的孩子们喜欢彼此通信,每封信都用单独的信封通过传统的邮政服务发送。每个家庭有一个孩子负责收发邮件,北京家庭是 阿京,而广州家庭是 阿州。每周阿京去她所有的兄弟姐妹那里收集邮件,并将这些邮件交到邮递员处上。当信件到达北京家庭时,阿京也负责将信件发到她的兄弟姐妹手上,广州家庭中 阿州也负责类似工作
网络层——邮递员
运输层——阿京和阿州
应用程序——兄弟姐妹
主机——两个家庭
通过运输层协议,两台电脑仿佛直接相连一样。应用无需知道底层内部实现的原理和细节,比如怎么把远隔世界两地电脑上的数据进行相互传输
Q2:注意点
运输层协议仅仅实现在网络的边缘处,例如主机,电脑,手机等。如路由器,交换机这些网络核心设备,是没有实现运输层协议的
每一层协议仅仅检查分组相应的协议层字段
最常用的两种输入层协议,
TCP
和UDP
运输层的下面是网络层,网络层的目的在于为不同的主机提供逻辑通信,而非主机上的进程
网络层常用协议是
IP
,其提供的是一种不可靠的数据传输服务为了做到为不同主机 (
host
) 上的应用或者说进程提供逻辑通信这一目的,运输层协议必须能分辨出数据的来源和去向。为此,运输层存在着两种行为,多路复用和多路分解
二.多路复用与多路分解
多路复用:当运输层收到来自上方应用层的数据时,运输层会为数据封上一些头部信息,根据所有协议不同,封上的信息也不一样
用上面的两个家庭的例子进行形象化地阐述就是:多路复用就是阿州和阿京将兄弟姐妹的信一起交给邮递员
多路分解:当运输层收到下方网络层传输来的数据时,运输层会检查多路复用时封上的信息,从而正确的把数据定向到相应的进程
Q1:如何使用运输层的协议?
操作系统提供了被称为 socket
的接口 api
供编程人员调用,对 socket
的形象理解是其是一种抽象,将复杂的实现 (tcp/udp
) 协议的各种行为抽形成简单的几个函数给开发人员使用。就像浏览器将发送请求报文这一 http
协议规定的行为,抽象成我们只需要输入 url
然后回车即可
这里需要注意的一点是:
在一般情况下,一个计算机端口只能被一个进程占用
一个进程可以创建多个
Socket
,多个TCP
Socket
可以监听同一个端口,并保证接受的数据依旧是正确的多个
UDP Socket
就无法监听同一端口,这其中的差异源于TCP
和UDP
协议的不同
TCP
是面向连接的,其有足够状态的信息来分辨数据来源,后定向到正确的socket
UDP
不需要维持连接,仅仅通过端口号来决定数据的去向,所以会导致冲突
三.UDP
和TCP
的多路复用和分解
Q1:UDP
的多路复用和分解
一个 UDP Socket
通过一个二元组 (目的 IP
地址,目的端口号) 来标识,当输入层收到数据时,通过检查这个二元组,来定向数据该去往哪一个 UDP Socket
。这也是多个 UDP Socket
无法监听同一个端口的原因
Q2:TCP
的多路复用分解
一个 TCP Socket
通过一个四元组 (源 IP
,源端口,目的 IP
,目的端口号) 来标识,这也解释为什么多个 TCP Socket
可以监听同一个端口,尽管目的 IP
和目的端口号是一样的,但是源 IP
和源端口的组合总是不同的
四.UDP
4.1 UDP
基本概念
相比于 TCP
来讲,UDP
是一个简单的协议,就是把网络层 IP
提供的服务封装了下,实现了多路复用和分解,提供了端到端进程间的通信和错误检验服务
相对于 TCP
来说:
缺点:
UDP
是不可靠的传输服务没有流量和拥塞控制
优点:
能够够精细的控制数据的发送时间和速率
无需事先建立连接
无连接状态
分组首部开销小
UDP
报文端结构:
源端口号:发送方的端口号
目的端口号:接收方端口号
长度:包括首部在内的报文长度
检验和:用来差错检验。只发现错误不纠正,错了就扔。然后重发
4.2 可靠数据传输
Q1:数据传输可能遇到的问题:
传输中数据被损坏
数据丢失
数据可能乱序到达
Q2:解决方法:
检验和
序号
定时器
肯定和否定反馈分组
Q3:如何在保证可靠性的前提下,提高其性能?
通过引入流水线 (
pipelining
) 技术
引入流水线导致了:
序号范围需要增加
收发双方可能需要缓存乱序到达的分组
以上两个的具体实现取决于传输协议如何处理分组丢失、损坏的问题 (是选择回退 N 步,还是选择重传)
Q4:如何处理分组丢失、损坏的问题
A.回退 N
步
其核心在于,发送方会维持一个窗口,发送方能发送的数据量取决于窗口长度,并且当丢失时会重送所有未确认的分组
接收方会丢弃乱序到达的缓存
特点:
1.累计性
ACK
2.单一定时器
B.选择重传
核心在于,收发双方都会维持一个窗口,并且尽力保证窗口的状态是同步的,因此当分包丢失时,发送方只会重送丢失的分组
接收方会缓存乱序到达的分组
特点:
1.独立性
ACK
2.多个定时器
五.TCP
5.1 TCP
基本概念
A.特点:
面向连接
全双工的
点对点,不存在一次发送将数据传递给多个接收方、
在合适的时候发送 发送缓存 里的数据
为每个数据封上一个
TCP
头部TCP
连接的每一端都具有发送缓存和接受缓存
B.报文段结构
部分参数解释:
序号 (
seq
) :所带数据的第一个比特的序号,同时也是接收方期待的序号,等于接收方回复报文中的ACK
(n) 中的 n确认号 (
ack
) :对于一个ACK
(n) 来说,告诉对方 n-1 前的数据已经收到,下一次期待的序列号为 nACK
:指示,用于指示报文中确认号字段的值是有效的PSH
:指示,立即发送_发送缓存_里的数据RST
:指示,用于强制关闭连接SYN
:指示,用于握手阶段也就是建立连接的阶段FIN
:指示,用于正常关闭连接接受窗口 :用于
TCP
的流量控制功能
5.2 可靠数据传输
TCP
协议为数据的每一Byte
都编号,而非针对报文段总是维持最老未经确认的 1
Byte
的计时器每一次超时重置的计时器时间会加倍
其错误恢复机制是回退 N 步和选择重传的混合体
不会丢弃乱序到达的分组,而是缓存起来
采用累计性
ACK
(回退N步的特性)只会重传丢失报文段中的数据(选择重传的特性)
快速重传:当接收到连续的三个重复冗余
ACK
(其实是收到四个同样的ACK
,第一个是正常的,后三个才是冗余的),会触发快速重传,立即重发分组
为什么是三个重复冗余
ACK
呢?答案:把三次冗余
ACK
作为判定丢失的准则其本身就是估计值。详细的探究过程请参考:TCP的快速重传机制
5.3 流量控制
为了防止过高数据流量导致接收者的接受缓存爆掉,接收者会在其
TCP
报文中通过 接受窗口 指示发收者还能发送多少数据
接受窗口 (rwnd
) 公式:
rwnd = RcvBuffer - [LastByteRead - LastbyteRead]
且:
LastByteSent - LastByteAcked <= rwnd
5.4 TCP
连接管理
Q1:建立连接(三次握手)
客户端发送
SYN
位置 1 的报文段服务端返回
SYN
为 1,ACK
为 1 的报文段客户端发送
ACK
为 1,且附带数据的报文段
形象化地理解:
TCP 三次握手
就好比两个人在街上隔着50米看见了对方,但是因为雾霾等原因不能100%确认,所以要通过招手的方式相互确定对方是否认识自己。张三首先向李四招手(
syn
),李四看到张三向自己招手后,向对方点了点头挤出了一个微笑(ack
)。张三看到李四微笑后确认了李四成功辨认出了自己(进入estalished
状态)但是李四还有点狐疑,向四周看了一看,有没有可能张三是在看别人呢,他也需要确认一下。所以李四也向张三招了招手(
syn
),张三看到李四向自己招手后知道对方是在寻求自己的确认,于是也点了点头挤出了微笑(ack
),李四看到对方的微笑后确认了张三就是在向自己打招呼(进入established
状态)。于是两人加快步伐,走到了一起,相互拥抱
Q2:断开连接(四次挥手)
客户发送
FIN
为 1 的报文段服务端返回
ACK
为 1 的报文段服务端发送
FIN
为 1 的报文段客户端返回
ACK
为 1 的报文段客户端在一段时间后,关闭连接
形象化地理解:
张三挥手(
fin
)——李四伤感地微笑(ack
)——李四挥手(fin
)——张三伤感地微笑
六.拥塞控制
Q1:拥塞的代价
导致分组过长的排队时延
需要重传因缓存溢出丢失的分组
高延时导致重送分组
丢包导致运输相关分组的分组交换器所作的工作全部白费
Q2:TCP
的拥塞控制
TCP
采用端到端的拥塞控制三个主要问题:
一个
TCP
的发送方如何限制自己的发送流量的速率?
通过设置一个拥塞窗口 (cwnd
), 并且保证:LastByteSent - LastByteAcked <= min{cwnd, rwnd}
如何感知其发送路径拥塞了?
timeout
收到一次正常
ACK
后连续收到三次冗余ACK
感到拥塞时,采用什么样的算法改变发送速率?
慢启动
cwnd
的值从 1 MSS
开始,并且对每一个 ACK
,cwnd
值变为原来的 2 倍,直到超过阈值 (ssthresh
),转为拥塞避免模式
拥塞避免
在每一个 RRT
时间,cwnd
的值增加一个 MSS
快速恢复
cwnd
的值降为一半加上重复收到的重复 ACK
的数量,并且每一个 ACK
,cwnd
的值增加一个 MSS
在实践中,一旦 timeout
就会会到慢启动的状态,多次重复 ACK
则会进入快速恢复状态
Q3:TCP
公平
TCP
的公平性在于保证每个连接的吞吐量是平均的,而不是应用或进程间
七.再谈握手和挥手
7.1 为啥一定要三次握手,两次不行吗?
弄清这个问题,我们需要先弄明白三次握手的目的是什么,能不能只用两次握手来达到同样的目的。
第一次握手:客户端发送网络包,服务端收到了。这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
第二次握手:服务端发包,客户端收到了。这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。
第三次握手:客户端发包,服务端收到了。这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。
因此,需要三次握手才能双方确认双方的接收与发送能力是否正常
试想如果是用两次握手,可能会出现下面这种情况:
如客户端发出连接请求,但因连接请求报文丢失而未收到确认,于是客户端再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接,客户端共发出了两个连接请求报文段,其中第一个丢失,第二个到达了服务端,但是第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达服务端,此时服务端误认为客户端又发出一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接,不采用三次握手,只要服务端发出确认,就建立新的连接了,此时客户端忽略服务端发来的确认,也不发送数据,则服务端一直等待客户端发送数据,浪费资源
7.2 为啥挥手要四次?
这是因为服务端在LISTEN
状态下,收到建立连接请求的SYN
报文后,把ACK
和SYN
放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN
报文时,仅仅表示对方不再发送数据了但是还能接收数据,所以服务端可以立即close
,也可以发送一些数据给客户端后,再发送FIN
报文给客户端来表示同意现在关闭连接,因此,服务端ACK
和FIN
一般都会分开发送。
如果文章对您有一点帮助的话,希望您能点一下赞,您的点赞,是我前进的动力
本文参考链接:
《计算机网络-自顶向下方法》
面试官,不要再问我三次握手和四次挥手
TCP的三次握手四次挥手
跟着动画来学习TCP三次握手和四次挥手
第三章-运输层-阅读笔记
第三章:运输层 |《计算机网络:自顶向下方法》
TCP的快速重传机制
自顶向下 | 带你遨游运输层相关推荐
- 百变精灵、灵萌仙宠,《神都降魔》带您遨游仙界!
目前最新火爆的一款史诗级回合制Q版卡牌仙侠手游<神都降魔>即将震撼来袭,游戏中拥有丰富的PVP内容对决和纯正的仙侠手游风格而备受广大玩家的青睐和关注,虽然还未正式上线却已经获得较多的关注和 ...
- 社科院与杜兰大学金融管理硕士——承载梦想,带自己遨游世界的“风帆”
每次归程,都是为了更好出发,每次停歇,都是为了积攒力量.人生成长的每一分钟,所有时间都花在自己身上,最终让我们有了一定的认知和满身的本领.知识是需要积累和沉淀的,也是需要适当补充的.在职读研承载了我们 ...
- 计算机网络自顶向下 第3章 运输层
3.1 概述和运输层服务 作用:为运行在不同主机上的应用进程之间提供了逻辑通信(logic communication)功能. 在运输层的分组称为运输层报文段(segment), 3.1.1 运输层和 ...
- java+usb+教程,带你遨游USB世界
1.什么是USB USB的全称是Universal Serial Bus,通用串行总线.它的出现主要是为了简化个人计算机与外围设备的连接,增加易用性.USB支持热插拔,并且是即插即用的,另外,它还具有 ...
- 【WebAR】小沐带您遨游太阳系(model-viewer,trimesh,Python)
文章目录 1.准备工作 1.1 gltf 1.2 usdz 1.3 trimesh (python) 1.4 model-viewer (javascript, WebAR) 2.八大行星 2.1 M ...
- 带您遨游太空,美摄科技为航天创意小程序提供全面技术支持
"北斗"指路."嫦娥"探月."天问"探火--近年来,中国在探月工程.载人航天等领域取得一批重大科技成果.近日,正值全国两会召开,全国政协委员 ...
- 带你揭秘学习编程的7大优势!你get到了吗?!
01 强化逻辑思维能力 可能会有不少人觉得,学习编程能锻炼逻辑思维能力.提高学习效率的说法太过空泛. 但当我们面对复杂繁琐的步骤头疼不已时,编程锻炼出来的思维方式能够高效地将问题化繁为简,这就是编程之 ...
- 再谈Android View树
小手动一动,点赞转发加关注.微信搜索[大前端杂货铺]公众号关注大前端老司机带您遨游大前端知识的海洋.关注 Github https://github.com/big-frontend 还有大前端代码实 ...
- c bool 类型检查_C语言和C+的区别是什么?8个点通俗易懂的告诉你!
有些初学的同学傻傻分不清其中的区别,下面我将详细的讲解C语言和C++的区别点帮助大家尽快的理解.(但是呢,C语言和C++可是有着密不可分的关系哦,一般学习其中一种都会需要学习另一种!) 1.关键字 蓝 ...
最新文章
- 记录本地Hexo博客部署到服务器上
- cocos2d-x游戏实例(28)-简易动作游戏(6)
- 前端学习(1142):预定义类
- java jdom 设置第1行_Java通过jdom操作生成XML文件的实例代码下载
- console输出彩色字体
- php 数字加逗号,PHP数字格式化,数字每三位加逗号
- 树莓派组网 ad-hoc模式
- wjw的剪纸(DFS)
- 【腾讯云服务器+PicGo搭建自己的图床】利用腾讯云服务器搭建自己的私人图床
- 导入Unity的模型在播放动画时手脚会轻微晃动(抖动)
- Linux系统编程1——系统函数
- java性别分类汇总,excel表格数据男女分类汇总-在Excel中,对数据清单进行“按性别分类汇总出男女......
- android开发指南!阿里P7级别面试经验总结,知乎上转疯了!
- 如何禁用windows10的3389端口
- 解决Intel12代酷睿CPU单线程只给小核运行的问题
- Unity 使用柏林噪声(Perlin Noise)生成网格地图
- QQ截图的这些功能你知道吗?可以提高工作效率
- 逾期率的水有多深,你知道吗?
- AndroidStudio报错:Failed to start monitoring CJL0217113005096
- FPDLINK与GMSL汇总
热门文章
- 如何接入微信公众号开发?底层原理是什么?
- 含章节号的题注编号以阿拉伯数字显示
- java笔记 ActionListener
- 江苏python二级考试时间,江苏2021年3月计算机二级考试报名时间安排
- 史上最简单MYSQL教程详解(基础篇)之初识MySQL数据库以及环境配置
- WebService系列之SSL异常handshake failure处理方法
- C语言学堂在线测试题防丢失汇总
- 下垂控制的两电平三相桥式逆变器,可根据负载的变化改变三相输出电压的频率和幅值
- python一组数字按大到小输出_Python练习题 005:三个数字由大到小排序输出
- SAP 固定资产减值准备