学习的课程及图片来源:中科大郑烇、杨坚全套《计算机网络(自顶向下方法 第7版,James F.Kurose,Keith W.Ross)》课程
传输层加强了网络层的服务,但有些服务是可以加强的,有些服务是不能加强的,如延时和带宽是不能加强的,取决于网络层
复用/解复用技术:
将多条运输连接上的数据汇集到一条网络连接上传输。本来逻辑上是有多个进程之间的通讯线路的,但通过复用(标识两者之间)只需要一条线路即可,在目标端对所有的信息解复用,分发给不同的应用进程
仅仅在IP上增加了复用和解复用功能
事务性:一次往返就结束
要在UDP上提供可靠传输,既利用UDP的高效,又要可靠,那么只能在应用层增加可靠性
(没有第三种协议,因为TCP、UDP能够支持85%以上的应用,再增加会出现协调等问题)
数据报:无连接的,每个数据单元都是独立发送的
校验和是验证报文传输过程中有没有出错,如果发现校验不对,那么这个UDP报文会被丢弃
在计算校验和的时候,需要在UDP数据报之前增加12字节的伪首部,伪首部并不是UDP真正的首部。只是在计算校验和,临时添加在UDP数据报的前面,得到一个临时的UDP数据报。校验和就是按照这个临时的UDP数据报计算的。伪首部既不向下传送也不向上递交,而仅仅是为了计算校验和。这样的校验和,既检查了UDP数据报,又对IP数据报的源IP地址和目的IP地址进行了检验。
UDP报文的头部小,固定的8个字节的头部,如上,64 bit。载荷即有效传输的数据部分占比大
将报文段(包含数据和头部,甚至有一些IP的伪头部)切分成若干个16 bit,将所有的16 bit数字加起来,注意求和时高位有进位需要进位回滚(将进到更高位的1加到最低位上去)。最后和再取反码,得到校验和。
收到数据报校验时,计算出所有的和,然后再加上校验和,得到全1,0xFFFF,那么说明没有出错(可能有残存错误)
RDT在有些网络中在网络层实现,通常是由TCP在传输层实现
要向上层应用提供可靠的服务,但是所依赖的下层服务却是不可靠的 (best effort)。
渐进地开发RDT:先假设下层是完全可靠的,再逐个去掉假设,变成不可靠的,从而处理这个不可靠,再将其变成可靠,逐个进行,直到所有假设都去掉
仅仅是封装和解封装即可
使用校验和 checksum来检验错误
但是显然ACK/NAK也是可能出错的【这个信息同样是需要校验的,校验和】,因此发送方可能无法判断接收方返回的信息是什么
停止等待协议 stop-and-wait protocol :每发送完一个分组就停止发送,等待对方的确认。在收到确认后再发送下一个分组。
取消NAK,而是对ACK编号,使用前一个分组(即最后一个正确接收的分组)的ACK作为该分组的NAK
这样可以为后续一次发送多个分组做好准备
同理ACK传输错误和上面RDT 2.1一样处理即可
增加了分组可能丢失的情况
超时重传机制:重传时间一般设置为比正常一个往返稍长一点的时间,一旦超过这个时间,一般就能确定分组丢失,然后重传即可
如果是ACK丢失了,那么重传会导致数据重复问题,但接收方可以根据分组序号知道重复,从而丢弃即可
在上面的有限状态机图中,右上角可以看到如果收到的ACK乱码/与发出的编码不匹配,说明需要重发,但这样是空,即不做处理,原因是想通过超时来处理,因为没有收到正确的,最终会导致超时,从而重发
设置一个合律的timeout很重要,如果设置时间太短了,也能正常工作,但会导致分组的发送和应答重复,效率低,如下
RDT 3.0对于停止等待协议是完备的,可以处理所有的情况
但停止等待协议的效率很低,特别是在信道容量(同时能容纳的“车“的数量,等于TR,R是带宽,T是信道从头到尾传输的时间)很大时,就像告诉公路很长,其中同一时间可以容纳很多车辆前后排列,但如果一次仅仅一辆车在行驶,行驶出高速公路后再让下一辆车上高速,显然效率太低了
传输时间=分组长度/链路带宽
可见,传输时间远小于往返延迟RTT,因此时间利用率很低0.027%,只有传输时间是在忙的,其他时间都是空闲的,等待信息的返回
有效吞吐=带宽*时间利用率=270kbps,相当于1Gbps的链路只用到了270kbps
流水线协议 pipeline protocol :一次发送多个未经确认的分组
Sliding-window protocol
发送窗口大小 | 接收窗口 | |
---|---|---|
停止等待协议 | 1 | 1 |
流水线协议——GBN | >1 | 1 |
流水线协议——SR | >1 | >1 |
发送窗口是发送缓冲区的子集,是指发送但未确认的分组
上层应用可以继续将要发送的分组存放在发送缓冲区,当发送后发送窗口的前沿便移动一格,最大可以到发送缓冲区的大小
接收窗口=接收缓冲区
【SR和GBN原理一样,都是序号最小的到来才移动,并且窗口中要包含到来的分组序号才会接收并返回ACK,否则丢弃】
GBN接收窗口大小是1,0,1分别到来,然后接收方分别接收解封装,并将数据data交给上层,再返回ACK0,ACK1,接收窗口向右移动,但如果下一个到来的是3而不是2,说明乱序,那么接收方会把3号分组丢弃,然后发送顺序到来的序号最大的分组的确认【累计确认,表明这个序号及以前的分组已经接收】即ACK1,接下来又来了4号分组,同样丢弃并且返回ACK1
SR中滑动窗口大于1,比如上面为5,先到了0,那么接收窗口右移一格,包含12345,然后返回ACK0,顺序到来1,接收窗口再右移一格,包含23456,返回ACK1,但接下来到来3,说明乱序,但由于接收窗口中可以包含3,说明可以接收3,那么会返回ACK3【非累计确认,仅仅是这个分组的独立确认**】,但接收窗口不移动,仍然包含23456,接下来到来4,返回ACK4,,接收窗口仍不移动,只有接收窗口中序号最小的到来才会导致移动。如果这时候来了2,会返回ACK2,因为此时234都到了,那么接收方会将234一起有序的交给上层(要有序交给上层,因此在乱序时要缓存),并且接受窗口右移3格
出现了前面的2号没有收到,收到3时接收方返回ACK1,那么发送方的发送窗口不能移动
【但是注意,如果此时发送窗口<发送缓冲区,那么发送缓冲区内的分组是可以被发送的,被发送后进入发送窗口。同理如果缓冲区中的分组未满,那么上层是可以将新的分组放到发送缓冲区的】
那么2号分组的计时器会超时timeout,因此发送方需要将发送窗口(即已发送但未确认的分组)全部再顺序发送一遍【因为GBN中2号分组没到,那么后面的所有分组都会被丢弃】
【注意:GBN中只有一个计时器,即在滑动窗口大小从0变成1时启动一个计时器,同时也只需要对最小序号的分组计时即可。当收到最小序号的ACK时,那么会把计时器重置,发送窗口右移动;如果收到ACK后,窗口大小变成0,那么关闭计时器;在超时重发时也会重置计时器】详见下面的FSM
出现了前面2号分组没收到的情况,但34号分组已经收到,那么2号分组会超时timeout,那么2号分组会被单独重发,但34号分组的计时器因为收到了确认ACK,所以不会被重发
但注意发送方的发送窗口仍然是不能移动的,因为2没有被确认,2被确认后,发送窗口同样移动3格
【注意:SR的每一个分组发送后都会有一个计时器分别计时,因此较为复杂】
对于SR,会出现如上图b的情况,因此在最坏的情况下即发送方发出的所有报文均被接收方接收,但ACK报文全部没有返回【关键是最小序号的ACK没有返回到发送方】,这时发送窗口不变,接收窗口右移发送窗口的大小,一旦超过了报文的序号,那么就会出现问题,一段的序号0的报文发给了下一段0的报文
因此要求的是NS+NR≤2n(其中序列号为0~2n-1)
[因此如果SR中两个窗口大小一样的话,每个最大只能是2n/2=2n-1;GBN中NR=1,因此发送窗口最大为2n-1]
MSS maximum segment size **最大报文段大小 **
MSS是TCP层交互给IP层最大分段大小,不包含TCP报头,只包含数据。
对于以太网,数据的MTU最大传输单元是1500B,因此应用进程的数据太大是无法被链路层的帧封装的,所以需要拆分。
应用进程的数据到了TCP实体后要根据MSS划分成不同的报文段,并且在每一个前面加上TCP头部
全双工(Full Duplex)全双工指可以同时(瞬时)进行信号的双向传输(A→B且B→A)。指A→B的同时B→A,是瞬时同步的。
单工就是在只允许甲方向乙方传送信息
TCP头部长度至少20 B,但还有一些可选项以一起构成头部,其中的首部长度就记录了头部的长度,用以区分出数据部分
序号指的是一个TCP数据报的数据部分的第一个字节在整个字节流中的偏移量,字节为单位。
即指的是segment中第一个字节的在整个字节流中的编号,而不是segment的编号
此外序号通常不是从0开始,而是开始建立TCP连接时,双方随机选择序列号。防止被攻击者猜到,或与其他冲突,所以设置随机
确认号是指确认n-1及以前的字节,比如ACK 555,那么就表示554及之前的都已经收到了,期待555,类似GBN,也是累计确认:该序列号之前的所有字节均已被正确接收到
Q:接收方如何处理乱序到达的Segment?
A:TCP规范中没有规定,由TCP的实现者做出决定,可以缓存,也可以直接抛弃
动态自适应地改变计时器的时间
1-α<1,因此随着测量的增加,前面的SampleRTT对平均值的影响会越来越小,而逐步过渡到后面的SampleRTT
E s t i m a t e d R T T = ( 1 − α ) ∗ E s t i m a t e d R T T + α ∗ S a m p l e R T T EstimatedRTT= (1- \alpha)*EstimatedRTT+\alpha*SampleRTT EstimatedRTT=(1−α)∗EstimatedRTT+α∗SampleRTT
右边的平均RTT是指之前计算出来的平均RTT
推荐值α=0.125
计算平均值的同时计算SampleRTT偏离平均值的平均情况,类似一种方差,称为安全边界时间DevRTT
D e v R T T = ( 1 − β ) ∗ D e v R T T + β ∗ ∣ S a m p l e R T T − E s t i m a t e d R T T ∣ DevRTT= (1-\beta)*DevRTT+\beta*|SampleRTT-EstimatedRTT| DevRTT=(1−β)∗DevRTT+β∗∣SampleRTT−EstimatedRTT∣
推荐值β=0.25
最终得到合适的超时时间间隔为平均RTT+4倍的安全边界
T i m e o u t I n t e r v a l = E s t i m a t e R T T + 4 ∗ D e v R T T TimeoutInterval = EstimateRTT+4*DevRTT TimeoutInterval=EstimateRTT+4∗DevRTT
TCP采用pipe-line 是GBN和SR的混合体
RDT:
触发重传:
超时:只发生最早的那个未确认的段,即发生超时的这个段
【超时定时器是比较保守的,在4倍偏差,因此如果超时,可以有极大的把握确定报文丢失】
重复的ACK:收到了1个正确ACK,然后又收到3个冗余的重复ACK,那么重传,而此时超时定时器还没超时,因此称为快速重传
NextSeqNum相当于滑动窗口的前沿
SendBase相当于滑动窗口的后沿。
只不过TCP中的窗口以字节为单位
累计确认,因此即使ACK=100没到,也没关系,ACK=120就能代表ACK=100
到了一个报文段后等待500 ms,如果第二个报文段在500 ms没来,那么发送第一个的ACK
如果上面等待过程中第二个连续的报文段到达,立即发送第二个报文段的累计确认,同时确认两个报文段
乱序到达,需要的一个报文段比如第一个字节位置为y0,而到达了第一个字节大于y0的,说明乱序,立即发送重复的ACK=y0,表示对y0的期待,让发送方重发
如果在3的情况中,到达了能够完全补充gap,即y0到乱序报文起始处的报文,那么立即发送乱序到达的报文的后面一个字节的的位置ACK,累计确认
如果是部分补齐,如上,在立即发送部分补齐的报文的后一个字节的ACK,让发送方快点补齐
快速重传:在定时器超时之前重传
收到1个正确ACK后又收到3个重复ACK,那么说明丢失的可能性非常大,需要重传
Q:为什么是三次?
A:因为无法判断是因为乱序还是丢失,重传1到2次更可能是乱序,3次及以上更可能是因为丢失
接收buffer通常默认为4096
接收方返回ACK时在receive window中记录其空闲的buffer的大小,从而发送方会限制其发送缓冲区中未确认的字节个数≤receive window值
piggyback捎带技术,即发送方和接收方是随时变化的,客户端发送数据给服务器,服务器也会发送数据给客户端,所以如果发送一次对方要返回一个确认,然后又发送数据回来,会比较麻烦,因此可以将确认放在数据中一起发送回来,即捎带
连接建立的本质:知道和要对方通信,准备好资源,控制变量做置位(特别是连接的初始序号#seq,对方的receive buffer的大小)
二次连接不可行
理论上3次是最少需要的
Client发送连接建立请求SYN=1并携带它将要从序号为x处开始传Seq=x
服务器会分配缓存
server需要对这个信息进行ACK,ACKNum=x+1【期望x+1及之后的数据】
然后server需要SYN=1并将自己从序号为y处开始传Seq=y告诉client
这两个信息2,3可以合并在一起SYN&ACK**(piggyback)**
然后client对server的y进行确认ACKNum=y+1【期望y+1及之后的数据】
这个ACK通常会和第一次数据传递放在一起
Q:会不会在三次握手的第二步服务器就会分配资源?
A:会分配,会保留一段时间直到确认这个ACK不会再建立了(SYN泛洪攻击,DDoS)
对称释放,并不完美
四次挥手是由于 TCP 的半关闭(half-close)特性,TCP 提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力
[结束发送指的是不再发送数据,但可以对对方的请求作出应答]
TCP 连接的释放需要发送四个包(执行四个步骤),因此称为四次挥手(Four-way handshake),客户端或服务端均可主动发起挥手动作。
1)第一次挥手:客户端发送一个 FIN 报文(请求连接终止:FIN = 1),报文中会指定一个序列号 seq = u。并停止再发送数据,主动关闭 TCP 连接。此时客户端处于 FIN_WAIT1 状态,等待服务端的确认。
FIN-WAIT-1 - 等待远程TCP的连接中断请求,或先前的连接中断请求的确认;
2)第二次挥手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT状态。
CLOSE-WAIT - 等待从本地用户发来的连接中断请求;
此时的 TCP 处于半关闭状态,客户端到服务端的连接释放。客户端收到服务端的确认后,进入FIN_WAIT2(终止等待 2)状态,等待服务端发出的连接释放报文段。
FIN-WAIT-2 - 从远程TCP等待连接中断请求;
3)第三次挥手:如果服务端也想断开连接了(没有要向客户端发出的数据),和客户端的第一次挥手一样,发送 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态,等待客户端的确认。
LAST-ACK - 等待原来发向远程TCP的连接中断请求的确认;
4)第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答(ack = w+1),且把服务端的序列值 +1 作为自己 ACK 报文的序号值(seq=u+1),此时客户端处于 TIME_WAIT (时间等待)状态。
TIME-WAIT - 等待足够的时间以确保远程TCP接收到连接中断请求的确认;
注意 :这个时候由服务端到客户端的 TCP 连接并未释放掉,需要经过时间等待计时器设置的时间 2MSL(一个报文的来回时间) 后才会进入 CLOSED 状态(这样做的目的是确保服务端收到自己的 ACK 报文。如果服务端在规定时间内没有收到客户端发来的 ACK 报文的话,服务端会重新发送 FIN 报文给客户端,客户端再次收到 FIN 报文之后,就知道之前的 ACK 报文丢失了,然后再次发送 ACK 报文给服务端)。**服务端收到 ACK 报文之后,就关闭连接了,处于 CLOSED 状态。**因此服务器到客户端的连接关闭,整个 TCP 连接关闭
两次挥手就可以释放一端到另一端的 TCP 连接,完全释放连接一共需要四次挥手。
举个例子:A 和 B 打电话,通话即将结束后,A 说 “我没啥要说的了”,B 回答 “我知道了”,于是 A 向 B 的连接释放了。但是 B 可能还会有要说的话,于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”,A 回答“知道了”,于是 B 向 A 的连接释放了,这样整个通话就结束了。
无限大的缓存,则报文不会丢失
掌握路由器空闲空间,代价太大
当网络拥塞时,会出现超时重传,丢失重传等,因此此时想要达到更高的传输速率,输入的带宽要增大,比如为了能每秒传输100个分组,那么输入到链路的分组数目会大于100个
当分组经过了很多路由器,但在后面的一个路由器被抛弃了,那么它在前面所做的努力都会被浪费,这在网络拥塞时更加可惜,因为资源有限,有限的资源还被浪费了
ATM Asynchronous Transfer Mode 异步传输模式。具有分组交换和电路交换的优点,对应于OSI协议参考模型的第2层。
数据交换的单位是信元,可以认为是小分组,53B,5B的头部,48B的载荷,因此存储转发的时间非常短即可完成。
在电路交换中,每个节点花费1bit的存储时间,在分组交换中每个节点花费一个分组的存储时间,而在 ATM 中信元比 1bit 大,比一个分组小,只花费53B的存储时间。所以网络调度很容易,兼具两种交换网络的特性
ATM 网络具有很多模式,如 ABR available bit rate 弹性服务:如果网络轻载,那么用户可以使用网络的可用带宽,但当网络拥塞时,用户只能使用网络承诺的带宽,不能超过如1 Mbps
发送方在发送数据信元中间隔插入资源管理信元 RM ,其中的 bit 被交换机设置:
显性前向拥塞指示
置为1,那么将由接收端把 RM 信元的 CI bit 置1接收端不修改 RM 信元,并将其返回给发送方,从而发送方可用知道网络状况,控制发送速率
端系统自己感知拥塞,网络核心负担低
超时即认为是拥塞
出现**3次重复的冗余 **ACK 即认为轻微拥塞,即出现丢失,但还有一定传输能力(后面3个段都到达了,此时还没超时,因为超时时间比较保守,加上4倍偏差)
r a t e = C o n g W i n R T T B y t e / s e c rate = \frac{CongWin}{RTT} Byte/sec rate=RTTCongWinByte/sec
MSS 是最大报文长度
保证发送窗口是拥塞窗口和对方接收窗口的最小值,从而同时满足拥塞控制和流量控制
SS slow start 慢启动
每收到一个 ACK,拥塞窗口加 1 == 下一次的拥塞窗口是上一次的两倍
初始速率很慢,但是快速攀升
不考虑 SS 阶段,因为指数增加,时间可以忽略不计
因此平均吞吐量为 0.75 W / RTT
TCP 是公平的,均分瓶颈带宽
以两个连接 1 和 2 共享链路为例:
短时间是可能超过斜线的,因为路由器存在缓存,但长期是不可能的,分组会被抛弃。
当检测到拥塞后(这里不看 SS 只看拥塞避免阶段,SS 时间很短),两者都会回到斜线内部,然后 45° 地增加带宽(即两者都逐步增加1 MSS[假设两者的 MSS 是一样的]),最终可以达到两者均分带宽
上述两种情况就体现了一定的不公平性,还有一种情况,如果 AA’ 的 MSS 小于 BB’ 的 MSS 那么最终两者也无法达到均分带宽
因此 TCP 的公平是大致上的公平