1. 传输层协议概述
1.1 传输层的特点
传输层特点:
传输层提供
进程
和进程
之间的逻辑通信。
- 解释:比如你在发送一条QQ消息,消息会通过自己的
ip+端口
发送到目标的ip+端口
上,使得QQ消息能够跨网络衔接在另一主机的QQ进程上。- 注意:网络层提供的是
主机
和主机
之间的逻辑通信。复用和分用
- 复用:应用层所有的应用程序都可以通过传输层再传输到网络层。
- 分用:传输层从网络层收到数据后交付给相应的应用进程。
- 例子:
1. 在发送端用QQ和微信分别给接收端的一个主机发送消息:“你好”。QQ和微信就复用的传输层的UDP协议。
2. 接收端接受到QQ和微信的消息后,分别根据使用的UDP协议准确的将消息发送给对应的应用。
传输层对收到的报文进行
差错检测
。
- 注意:在网络层有一个IP首部校验和,这只是对IP首部进行校验,而IP数据的校验是由传输层先检测的,因为传输层的数据报构成IP数据报的数据部分。
- 由此可见:网络层 + 传输层 的校验能够使得数据是可靠传输(比如TCP),当然,根据需要也可以是不可靠传输(比如UDP)
传输层的两种协议:
TCP协议
:面向连接的协议,是可靠传输UDP协议
:不是面向连接的协议,是不可靠传输
1.2 传输层的寻址与端口
我们知道传输层的分用特点,那么传输层如何将从网络层中收到的消息发送给相应的进程??
其实是通过终端的端口实现的。一台计算机有多个端口,每个端口都可以对应一个进程,那么只要在发送端发送数据时,添上接收端接受数据的端口,那么接受端的传输层就会将数据发送给相应的端口,也就唯一找到了对应的进程。
注意:到这里,我们应该能够理解网络层的IP用来找到网络中的主机,而传输层的端口用来找到相应的进程。所以才说:
- 网络层是建立主机与主机间的逻辑通信;传输层是建立进程与进程间的逻辑通信。
另外,需要强调的是传输层的端口是逻辑端口(或者软件端口),而不是想交换机上的物理插口端口。
端口号只要本地意义,在Internet中不同计算机的相同端口是没有联系的。
注意:端口长度为
16bit
,也就是一台计算机有65536个端口号。
端口的分类:
下面是需要记住的几个应用所占用的端口号:
注意:TELNET是远程登入时用到。
在网络中采用发送方和接受方的套间字组合来识别两端点。套间字唯一标识了网络中的一个主机和它上面的一个进程,形式图如下:
2. 无连接的用户数据报协议UDP
2.1 UDP协议的特点
UDP只是对应用层(具体是会话层)的报文增加了很少的功能,即复用分用和差错检测功能。(可差流用,故不提供可靠传输和流量控制)
- UDP:传送数据之前不需要建立连接,收到UDP报文后也不需要给出任何确认。
- 主要特点:
- UDP是
无连接
的,减少开销和发送数据之前的时延。- UDP使用最大努力交付(即无差错传输),
不保证可靠交付
。
- 注意:如果此层不提供可靠性,那么上层某层必须提供可靠性。所以使用UDP协议的可靠性由
应用层
负责。(5层模型,ios模型,可以是会话层、表现层或应用层)- UDP是面向报文的,适合一次性传输少量合适的网络应用。
UDP无 拥塞控制 和 流量控制
,适合很多实时应用。- UDP首部开销小,8B,TCP>=20B
应用层到网络层的数据封装过程如下:
上面UDP的特点中提到了UDP是面向报文的。指的是:传输层使用UDP协议时,不处理应用层报文,不进行分组等等,而直接在其前面加上UDP头部,构成IP数据报数据部分。也就是应用层给UDP多长的报文,网络层加上IP首部后照样发送,即报文不可分割,一次发一个完整报文。
这就使得如果使用UDP协议,则应用层报文的长度必须适中。如果过长,会增加网络层的负担,降低效率,另外过长也更容易造成数据丢失(不可靠服务);如果过短,比如IP数据报的首都长度大于IP数据报数据部分,会造成传输的利用率降低。所以,UDP适合一次性传输少量合适的网络应用。
UDP 没有拥塞控制,一直会以恒定的速度发送数据。即使网络条件不好,也不会对发送速率进行调整。这样实现的弊端就是在网络条件不好的情况下可能会导致丢包,但是优点也很明显,在某些实时性要求高的场景(比如电话会议)就需要使用 UDP 而不是 TCP。
小结:
- UDP特点:不可靠、无连接、面向报文、时延小、具有实时性、适用于小文件。
- UDP是面向报文的。报文不可分割,一次发一个完整报文
- UDP没有可靠传输和流量控制
- UDP提供的是无差错服务,而不是可靠服务。
2.2 UDP首部格式
UDP的数据部分是可以为0的,所以一个UDP数据报至少为8B
大小。由于UDP长度标识占2个字节,单位为1B
,即整个UDP最大为65535B
。
源端口号是可以选填的,如果希望对方回消息就加上源端口好,否则,可以不加。
注意:
- 分用时,如果找不到对应的目的端口,就回丢弃报文,并给发送端发送ICMP“端口不可到达”差错报告报文。
- MAC地址长度
6B
,IP地址长度4B
, 端口长度2B
.
2.3 UDP校验
UDP校验时,会对UDP数据报构造一个伪IP数据报首部,用来检验UDP首部和数据部分是否出错(也就是IP数据报的数据部分)然后进行校验,其伪首部如下图所示:
注意:
- UDP的协议标志是17,TCP协议标志是6
- 伪首部只有在计算检验和时才出现。
- IP数据报的校验是只校验首部,而UDP用户数据报是校验
整个报文
和伪首部
,即:伪首部、首部、数据
接下来介绍UDP数据报校验的过程:
上面UDP数据报中的15表示整个UDP报文是15B,首部是固定长度8B,所以可以计算出数据部分是7B,需要填充1B的全零。
注意:
- UDP的校验不是必须的,如果不使用校验和,那么将校验和字段设置为0,而如果校验和计算结果恰好为0,那么将校验和全置1.
- UDP校验是二进制
反码
运算求和后再取反
。
3. 面向连接的传输控制协议TCP
3.1 TCP协议特点
- TCP:传送数据之前必须建立连接,传输结束之后要释放连接。不提供
广播或多播
服务。- 特点:
- TCP是面向连接的(虚连接)的传输层协议。
- 每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的,所以
无法进行广播或多播
。- TCP提供可靠交付的服务,无差错,不丢失,不重复,按序到达。(
可靠有序,不丢不重
)- TCP提供
全双工通信
。因此需要缓存:
- 发送缓存:
- 准备发送的数据
- 已经发送但尚未收到确认的数据
- 接收缓存:
- 按序到达但尚未被接受应用程序读取的数据
- 不按序到达的数据
TCP面向字节序列
。而UDP是面向报文的。
- 解释:TCP把应用程序交下来的数据看成仅仅是一连串的无结构的字节流。
上述特点中提到了TCP面向字节流,就是TCP将应用层传下来的数据报看做一个二进制流,然后分片后传给网络层,如下图所示:
由于TCP要提供可靠的面向连接的传输服务,因此不可避免增加了许多开销:确认、流量控制、计时器、连接管理等
TCP特点:面向连接、可靠传输、面向字节流、有流量控制、时延大、适用于大文件。
3.2 TCP报文段首部格式
注意:链路层以上的都是
先源后目
。MAC地址是目的地址,再源地址
,IP是先源IP,再目的IP
,TCP或UDP是先源端口,后目的端口
接下来解释上面的几个名词:
- 序号:在一个TCP连接中传送的字节流中的每一个字节都按顺序编号(一个字节占一个序号),TCP会以将字节分组发送,每一组数据放入发送缓存前都加上TCP头部,而TCP头部中又包含序号,序号是以所发送数据的第一个字节的序号。示意图如下:
- 确认号:期望收到对方下一个报文段的第一个数据字节的序号。若确认号为N,则指名到序号N-1为止的所有数据都已正确收到。
- 数据偏移(实际上指首部长度):TCP报文段的数据起始处距离TCP报文段的起始处有多远,以4B位为单位,即一个数值是4B.而IP的数据偏移是8B为单位
注意:数据偏移占4bit,15*4B=60B,所以TCP首部最长是60B.
小结:20B <= TCP首部长度 <= 60B;20B <= IP数据报的首部长度 <= 60B
- 紧急位URG(发送端):URG=1时,标明此报文段有紧急数据,是高优先级的数据,应该尽快传送,不用在缓存里排队,配合紧急指针字段使用。(大白话来说就是在缓存队列中插队)
- 确认位ACK(发送端):只有在ACK=1时,确认号字段有效,在连接建立后所有传送的报文段都必须把ACK置为1.
- 推送位PSH(接受端):PSH=1时,接受方尽快交付接收应用程序,不再等到缓存填满再向上交付。
- 复位RST:RST=1,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立连接。
- 同步位SYN:SYN=1时,表明是一个连接请求或者连接接受报文。
- 终止位FIN:FIN=1,表明此发送方数据已发完,要求释放连接。
- 窗口:指的是发送本报文的一方的接受窗口,即现在允许发送数据的数据量。 大多数情况下都是发送方接受缓存的大小。
单位是1KB
- 检验和:检验首部和数据部分是否出错,检验时要假设12B伪首部(和UDP一样)。和UDP一样,也是只有在校验的时候采用伪首部,最终校验的是
伪首部、首部、数据
- 紧急指针:URG=1时才有意义,指出本报文段中紧急数据的字节数。
- 选项:最大报文段长度MSS、窗口扩大、时间戳、选择确认…
3.3 TCP连接管理
TCP连接传输三个阶段:
3.3.1 TCP连接的建立:三次握手
TCP连接的建立采用客户服务器方式,主动发起建立连接请求的应用进程叫客户,而被动等待连接建立的应用进程叫服务器。
TCP连接的建立,即三次握手可以用一下一张图来形容:
具体过程如下,需要注意TCP头部字段的变化:
注意:
ACK = 1
时,确认号才有效。即ack有效。三次握手
建立连接和四次握手
释放连接中,seq是加1,seq = ack + 1
。输出过程中可能不是的。- 如果主机两端口间已经建立TCP连接,再在这两个端口上建立TCP连接会:连接建立失败,但是不影响先建立的连接。
3.3.2 SYN洪泛攻击
SYN洪泛攻击利用了TCP三次握手协议的漏洞,即每次请求都必须收到回应,否则资源会一直挂起。
解决方法:设置SYN cookie
3.3.3 TCP连接的释放:四次握手
TCP连接的释放可以用如下一张图来形容:
具体释放过程如下:
注意:
- 有一方发送了带有FIN标志的数据段后,表示单方面释放连接,表示本方已经没有数据发送了,但是可以接受对方的数据。
- 客户端在最后一步中,发送完确认报文后,需要等待一段时间。如果不等待的话,假设这个数据报丢失了,服务器收不到客户端的应答,过一段时间又会重新的发送连接释放报文,这样一直浪费资源。
3.4 TCP可靠传输
3.4.1 TCP可靠传输机制
由于网络层是不可靠传输,所以需要上层保证可靠性。如果需要网络层的上一层保证可靠性,则传输层必须使用TCP协议;否则可以使用UDP协议,使得可靠性由传输层的上层(应用层)来保证。
可靠:指的是接受方进程从缓存去读取的字节流和发送方发出的字节流是完全一样的。即发送方发送什么,接受方就接受什么。
* TCP实现可靠传输的机制:
1. 校验。和UDP的校验一样。
2. 序号
3. 确认
4. 重传
- 序号
注意:
- 以字节为单位编序号
- 报文段的序号字段是其数据部分的第一个字节的编号。
- 确认
假设不是按序到达的:
注意:
- TCP默认采用累计确认的方式。
- 报文段的序号字段是其数据部分的第一个字节的编号。报文段的确认字段是该报文的最后一个字节的编号。
- 重传:确认与重传是不分家的,TCP的发送方在规定的时间内没有收到确认就需要重传已发送的报文段。
- 那么,现在的问题是规定时间是多少?如果过短,会造成很多不必要的重传;如果过长,会降低网络资源的利用率。
- TCP采用的自适应算法,动态改变重传时间RTTs(加权平均往返时间)。
比如:
在传第一个数据报时,以第一个数据报的RTT为重传时间。
在传第二个数据报时,以第一个数据报和第二数据报的RTT加权得到RTTs,该RTTs为第二个数据报的重传时间。
注意:可能有的人会问,UDP也有差错检验,为什么不是可靠传输?
- 因为,UDP进行差错检测后,只是将检测的结果给了上一层的应用层,而没有返回给主机。而TCP是通过差错检测判断数据是否有错,再通过序号判断是数据丢失或数据重复等等,最后通过确认和重传机制,将错误发送给发送方,从而实现了可靠传输。
3.4.2 TCP快速重传
如果每次重传都需要将等待时间过完才可以确认数据报是否丢失,这样等的时间太长了,那么有没有其他的方法能快速的检测数据报是否丢失???
我们可以使用冗余ACK(冗余确认)的方法实现:
每当比期望序号大的失序报文段到达时,发送一个冗余ACK,指名下一个期待字节的序号。
比如:发送端已发送1,2,3,4,5报文段
- 接受方收到1,返回给1确认消息(确认号为2的第一个字节)
- 接受方收到3,返回给1确认消息(确认号为2的第一个字节)
- 接受方收到4,返回给1确认消息(确认号为2的第一个字节)
- 接受方收到4,返回给1确认消息(确认号为2的第一个字节)
- 发送方收到3个对于报文段1的冗余ACK->认为2报文丢失,重传2号报文段。从而实现了快速重传。
可以看到,如果收到失序报文后,将失序报文放在接受窗口中,再向发送方发送失序的确认报文。
3.5 TCP流量控制
为什么传输层需要流量控制?主要是因为让发送方慢点,要让接受方来得及接受。
TCP利用滑动窗口机制实现流量控制。(事实上就是动态设置TCP头部的窗口字段)
在通信过程中,接受方根据自己接受缓存的大小,动态地调整发送方的发送窗口大小,即接受窗口rwnd(接受方设置确认报文段的窗口字段来将rwnd通知给发送方)
发送方的发送窗口取接收窗口rwnd和拥塞窗口cwnd的最小值。
注意:滑动窗口大小要适当。
- 如果过小,会产生过多的ACK(大一点,可以充分利用累计确认的优点)
- 如果过大,会使得传送的数据过多,使得路由器变得拥挤,导致主机可能丢失分组。
下图是一个流量控制的例子:
-
上面存在一个隐患问题:
- 到最后一步之后,如果B给A的发送
ACK=1 ack=601 rwnd=100
,假设这个数据报丢失了,那么A和B都会处于等待状态,类似于操作系统中的死锁。那么如何解决????
- 到最后一步之后,如果B给A的发送
-
解决方法:
- TCP为每一个连接设有一个持续的计时器,只要TCP连接的一方收到对方的零窗口通知(也就是上述中的A方),就启动持续计时器。
- 若持续计时器设置的时间到期,就发送一个零窗口探测报文。接受方收到探测报文段时给出现在的窗口值。
- 若窗口仍然是0,那么重新设置持续计时器。
注意:
3.6 TCP拥塞控制
出现拥塞资源的条件:对资源需求的总和 > 可用资源
.
拥塞控制:防止过多的数据注入到网络中。(全局性。针对的是网络中的所有主机)
虽然流量控制和拥塞控制都是要求发送方协调发送速率,但是其本质上是不一样的。
流量控制是点对点的控制,是受接收端接受数据的速度影响。
而拥塞控制是多对多的,他并不知道具体是哪台主机的影响,是受整个网络中的主机影响。
假定:
- 数据单方向传送,另一方只接受数据。
- 接受方总是有足够大的缓存空间,因而发送窗口大小取决于拥塞程度。
因为 发送窗口大小 = min(接受窗口rwnd, 拥塞窗口cwnd)
注意:
- 接受窗口rwnd: (接受方设置)反应的是接受方的容量。根据
接受方
数据报的窗口字段获取。- 拥塞窗口cwnd: (发送方设置)反应网络当前容量。根据
发送方
估算的网络拥塞程度而设置的窗口值。- 发送窗口的大小是由
流量控制
和拥塞避免
共同决定的。窗口大小 = min(接受窗口rwnd, 拥塞窗口cwnd)
实际上,慢开始、拥塞避免、快重传、快恢复应该是同时运用在拥塞控制中的。当发送方检查到
超时
时,就采用慢开始和拥塞避免算法
;当发送方接受到冗余ACK
时,就采用快重传和快恢复算法
。
如果已经计算出了滑动窗口的大小,那么滑动窗口内的数据我们应该分几次发?每次发送多少个数据报?这就需要用到拥塞控制算法了,其有如下两种:
- 慢开始和拥塞避免
- 快重传和快恢复
3.6.1 拥塞算法:慢开始和拥塞避免
以上cwnd
的值指的是能够发送数据报的个数
上图就是慢开始和拥塞避免的算法。
注意:
- 首先解释一下x轴传输轮次:一个传输轮次指发送了一批报文段并收到他们的确认时间的整个过程。
- 而这个过程中花费的时间叫做往返时延RTT。
- cwnd=1,这个1是指一次发送一个报文段,且该报文段是一个最大报文段程度MSS.
- 从图中可以看到,遇到拥塞时,cwnd不是立即减少,而是在下一轮减少。
慢开始和拥塞控制的步骤描述:
- 首先是慢开始部分,慢开始是2^n指数形式,n从0开始。
- 慢开始到达
cwnd=16
时,取ssthresh从初始值为16
,进入拥塞避免部分。拥塞避免是线性函数,x增加1,y增加1.
注意:慢开始是
指数函数
,ssth不一定是16
,具体看题目给的ssth。如果题目没有给ssth,则指数无上限。
- 如果在拥塞避免部分遇到网络拥堵,则取下次的
取ssthresh从初始值为 当前cwnd/2
,并进入慢开始部分。如此反复。
注意:
- 区分题目说的慢开始与拥塞避免,还是快重传与快恢复。
- 一个报文段包含多个B。
3.6.1 拥塞算法:快重传与快恢复
快重传与快恢复是对慢开始和拥塞避免算法的改进。
上图就是快恢复的算法。而其中TCP快速重传在3.4.2
中已经说明。
该过程与之前的慢开始和拥塞避免类似,只是遇到网络拥塞的时候处理方法有一点点不一样。
4. 补充
4.1 window命令
doc下查看本机使用TCP/UDP的IP以及端口:
netstat -n
只查看使用TCP协议的端口。 n是指以数字形式显示地址和端口号,而不是以名称显示。比如localhost用127.0.0.1代替。netstat -an
只查看使用TCP或UDP协议的端口。
4.2 习题
发送窗口更新的时间并不是RTT完的瞬间才修改。因为在一个RTT内会逐个发送多个报文段,比如第一个RTT内会发送1个报文段,第二个RTT内发送2个报文段,第三个RTT内发送4个报文段…发送方每收到一个报文段的应答时,就改变窗口大小。而一个RTT在哪里结束,还需要借助cwnd的算法判断。【下题2,3就是例子】
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/84628.html