计算机网络 —— 运输层
Posted jl916
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算机网络 —— 运输层相关的知识,希望对你有一定的参考价值。
计算机网络 —— 运输层
- 复用(multiplexing):发送方不同的应用进程可以使用同一个运输层协议传送数据
- 分用(demultiplexing):接收方的运输层在剥去报文的首部后能够把这些数据正确交付目的应用进程
网络层为主机之间提供逻辑通信
运输层为应用进程之间提供端到端的逻辑通信
两种传输协议:
- TCP:Transmission Control Protocol,传输控制协议,面向连接,传送 TCP 数据报。
- UDP:User Datagram Protocol,用户数据报协议,无连接,传送 UDP 报文或用户数据报。
一、 Port 和 Socket
Port:protocol port number,协议端口号,简称为 端口。用一个 16 位端口号进行标志。
端口号只具有本地意义,即端口号只是为了标志本计算机应用层中的各进程。在因特网中不同计算机的相同端口号是没有联系的。
分类:
- 服务器端使用的端口号
- 熟知端口号或系统端口号 0 - 1023
- 登记端口号 1024 - 49151
- 客户端使用的端口号或短暂端口号 49152 - 65535
Socket:套接字,IP 地址 : 端口号。TCP 连接的端点。
二、 UDP
- 无连接:即发送数据之前不需要建立连接,因此减少了开销和发送数据之前的时延。
- 尽最大努力交付:即不保证可靠交付,接收方发现目的端口号不正确就丢弃报文,并由 ICMP 协议发送端口不可达差错报文。
- 面向报文:即一次发送一个报文,一次交付一个完整的报文。因此,应用程序必须选择合适大小的报文。
- 没有拥塞控制:因此网络出现的拥塞不会使源主机的发送速率降低。
- 支持一对一、一对多、多对一和多对多的交互通信。
- 首部开销小:8个字节
UDP socket:由 2 元组确定。目的 IP 地址,目的端口号。
首部字段:
- 源端口:不需要时可用全0。
- 目的端口
- 长度:UDP 用户数据报的长度,最小值是 8 (仅含首部)。
- 检验和:在计算检验和时,临时把伪首部和 UDP 用户数据报连接在一起。伪首部仅仅是为了计算检验和。
三、 TCP
- 面向连接:应用程序在使用 TCP 协议之前,必须先建立 TCP 连接。在传送数据完毕后,必须释放 TCP 连接。
- 每一条TCP连接只能有两个端点:即一对一。
- 可靠交付的服务:即通过 TCP 连接传送的数据,无差错、不丢失、不重复,并且按序到达。
- 全双工通信:即 TCP 允许通信双方的应用进程在任何时候都能发送数据。
- 面向字节流:TCP 对应用进程一次把多长的报文发送到 TCP 的缓存中是不关心的。TCP 根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少个字节。TCP 可把太长的数据块划分短一些再传送,也可等待积累有足够多的字节后再构成报文段发送出去。
TCP socket:由 4 元组确定。源IP地址,源端口号,目的 IP 地址,目的端口号。
首部字段:
- 源端口:2字节
- 目的端口:2字节
- 序号:4字节。即 (2^{32}(4294967296)) 个序号,序号到最大后回到 (0)。该字段指明本报文段所发送的数据的第一个字节的序号。字节流中的每一个字节都按顺序编号。整个要传送的字节流的起始序号必须在连接建立时设置。
- 确认号:4字节,期望收到对方下一个报文段的第一个数据字节的序号。若确认号 = N,则表明到序号 N-1 为止的所有数据都已正确收到。
- 数据偏移:4位,TCP 报文段的首部长度。单位是 32 位字(4字节),范围是 5-15,即 TCP 首部最小 20 字节,最大 60 字节。
- 保留:6位,保留为今后使用,但目前应置为0。
- URG:1位,URGent,紧急。为 1 时,紧急指针字段有效,它告诉系统此报文段中有紧急数据,应尽快传送(高优先级的数据),于是发送方 TCP 就把紧急数据插入到本报文段数据的最前面。
- ACK:1位,ACKnowledgment,确认。为 1 时,确认号字段有效。在连接建立后所有传送的报文段都必须把 ACK 置 1。
- PSH:1位,PuSH,推送。为 1 时,接收方尽快交付接收应用进程,而不再等到整个缓存都填满了后再向上交付。
- RST:1位,ReSeT,复位。为 1 时,释放连接,然后再重新建立运输连接。
- SYN:1位,SYNchronization,同步。在连接建立时用来同步序号。为 1 时,表示这是一个连接请求或连接接受报文。
- FIN:1位,FINis,终止。用来释放一个连接。为 1 时,表明发送方的数据已发送完毕,并要求释放运输连接。
- 窗口:2字节。指明发送本报文段的一方的 接收窗口,作为接收方让发送方设置其发送窗口的依据。即从本报文段首部中的确认号算起,接收方目前允许对方发送的数据量(以字节为单位)。
- 检验和:2字节。检验范围包括首部和数据这两部分。在计算检验和时,要加上 12 字节的伪首部。伪首部格式与 UDP 相同,但协议字段中的 17 应改为 6。
- 紧急指针:2字节。本报文段中的紧急数据的字节数,即指出紧急数据的末尾在报文段中的位置。
- 选项:长度可变,最长可达40字节。
- 最大报文段长度 MSS 选项
- 窗口扩大选项
- 时间戳选项
- 选择确认选项
- 填充:使首部是 4 字节的整数倍。
可靠传输
可靠传输原理
停止等待协议:每发送完一个分组就停止发送,等待对方的确认。在收到确认后再发送下一个分组。
超时重传:每发送完一个分组设置一个超时计时器。在超时计时器到期之前收到了相应的确认,就撤销该超时计时器。- 发送方暂时保留已发送的分组的副本。
- 分组和确认分组都必须编号。
- 超时计时器设置的重传时间应当比数据在分组传输的平均往返时间更长一些。
自动重传请求ARQ(Automatic Repeat reQuest):重传的请求自动进行,接收方不需要请求发送方重传某个出错的分组。
缺点:信道利用率极低。
(信道利用率 U = T_D / (T_D + RTT + T_A))流水线传输:发送方可连续发送多个分组,不必每发完一个分组就停下来等待确认。
连续 ARQ 协议:
发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置。
接收方:
- 累积确认:接收方不必对收到的分组逐个发送确认,而是对按序到达的最后一个分组发送确认,表示到这个分组为止的所有分组都已正确收到了。发送方维护最早未确认报文段的计时器,如果计时器时间到,则重传所有未确认报文段。
- 选择重传:接收方逐个的确认正确接收的报文。发送方为每个未确认的报文维护计时器,时间到,重传未确认的报文。
可靠传输实现
发送方的 发送窗口:在没有收到确认的情况下,发送方可以连续把窗口内的数据都发送出去。凡是已经发送过的数据,在未收到确认之前都必须暂时保留,以便在超时重传时使用。
发送窗口的位置由窗口前沿和后沿的位置共同确定。
发送窗口后沿的后面部分表示已发送且已收到了确认;前沿的前面部分表示不允许发送。
发送窗口后沿的变化情况有两种可能:即不动(没有收到新的确认)或前移(收到了新的确认)。
发送窗口前沿通常是不断向前移动,但也有可能不动。这对应于两种情况:一是没有收到新的确认,对方通知的窗口大小也不变;二是收到了新的确认但对方通知的窗口缩小了,使得发送窗口前沿正好不动。发送窗口前沿也有可能向后收缩。这发生在对方通知的窗口缩小了。但 TCP 的标准强烈不赞成这样做。
发送方的发送窗口跟据接收方的接收窗口设置,但在同一时刻,发送窗口并不总是和接收窗口一样大。
- 网络传送窗口值需要经历一定的时间滞后。
- 发送方还可能根据网络当时的拥塞情况适当减小自己的发送窗口数值。
TCP 要求接收方必须有累积确认的功能,这样可以减小传输开销。接收方可以在合适的时候发送确认,也可以在自己有数据要发送时把确认信息顺便捎带上。
TCP 的通信是全双工通信。通信中的每一方都在发送和接收报文段。因此,每一方都有自己的发送窗口和接收窗口。
此时,B 发送的确认报文段中确认号仍为 31。
现在,B 收到了序号为 31 的数据,并将31-33交付主机,发送确认号为 34 的确认报文段。
A 发送窗口内的序号都已用完,但还没有再收到确认。
此时发送窗口已满,可用窗口已减小到零,因此必须 停止发送。
如果 A 收到确认号落在发送窗口内,那么发送窗口继续向前滑动,并发送新的数据。
如果超时计数器到时,A 重传这部分数据,重新设置超时计时器,直到收到 B 的确认为止。
窗口与缓存的关系:
发送缓存 用来暂时存放:
- 发送应用程序传送给发送方TCP准备发送的数据;
- TCP 已发送出但尚未收到确认的数据。
发送窗口通常只是发送缓存的一部分。已被确认的数据应当从发送缓存中删除,因此发送缓存和发送窗口的后沿是重合的。发送应用程序最后写入发送缓存的字节减去最后被确认的字节,就是还保留在发送缓存中的被写入的字节数。发送应用程序必须控制写入缓存的速率,不能太快,否则发送缓存就会没有存放数据的空间。
接收缓存 用来暂时存放:
- 按序到达的、但尚未被接收应用程序读取的数据;
- 未按序到达的数据。
如果收到的分组被检测出有差错,则要丢弃。如果接收应用程序来不及读取收到的数据,接收缓存最终就会被填满,使接收窗口减小到零。反之,如果接收应用程序能够及时从接收缓存中读取收到的数据,接收窗口就可以增大,但最大不能超过接收缓存。
接收方 ACK 的产生:
事件 | 动作 |
---|---|
序号为#的按序报文段到达。所有到序号#的数据已经发送确认。 | 延迟确认。等待下一个报文段至多 500ms。如果没有下一个报文段,发送确认。 |
序号为#的按序报文段到达。另外一个报文段等待发送确认。 | 立即发送累积确认,确认这两个按序报文段。 |
比当前期望序号#高的乱序报文段到达。检测到空隙。 | 立即发送重复确认,表明下一个希望收到的按序报文段。 |
报文段到达,部分或全部填充空隙。 | 如果收到的报文段从空隙的起始开始,立即发送确认。 |
超时重传时间选择:
TCP 采用了一种自适应算法,它记录一个报文段发出的时间,以及收到相应的确认的时间。这两个时间之差就是报文段的 往返时间 RTT。
TCP 保留了 (RTT) 的一个加权平均往返时间 (RTT_S)。
第一次测量到 (RTT) 样本时,(RTT_S) 值就取为所测量到的 (RTT) 样本值。以后每测量到一个新的 (RTT) 样本,就按下式重新计算 (RTT_S = (1 - alpha) * RTT_s + alpha * RTT)
RFC 2988 推荐的 (alpha) 值为 0.125。
超时重传时间 RTO(RetransmissionTime-Out) 应略大于上面得出的加权平均往返时间 (RTT_S)。
RFC 2988 建议使用下式计算 :(RTO = RTT_S + 4 * RTT_D)
其中 (RTT_D) 是 (RTT) 偏差的加权平均值。第一次测量时,(RTT_D) 值取为测量到的 (RTT) 样本值的一半。在以后的测量中,则使用下式计算 (RTT_D = (1 - eta) * RTT_D + eta * |RTT_S - RTT| eta 推荐 0.25)
Karn 算法:在计算平均往返时间 RTT 时,如果报文段重传,不采用其作为往返时间样本。
报文段每重传一次,就把 RTO 增大为原来的 2 倍,最大值 64 秒。
选择确认 SACK:
接收方收到了和前面的字节流不连续的字节块。
如果这些字节的序号都在接收窗口之内,那么接收方就先收下这些数据,但要把这些信息准确地告诉发送方,使发送方不要再重复发送这些已收到的数据。
- 如果要使用选择确认,那么在建立 TCP 连接时,就要在 TCP 首部的选项中加上允许 SACK的选项。
- 在 TCP 报文段的首部中都增加了 SACK 选项,以便报告收到的不连续的字节块的边界。
- 首部选项的长度最多 40 字节,指明一个字块用掉 4 * 2 字节,因此在选项中最多只能指明 4 个字节块的边界信息。
流量控制
利用滑动窗口机制实现。
B 向 A 发送了零窗口的报文段后不久,B 的接收缓存又有了一些存储空间。于是 B 向 A 发送了 rwnd = 400 的报文段。但这个报文段在传送过程中丢失了。A 一直等待收到 B 发送的非零窗口的通知,而 B 也一直等待 A 发送的数据,产生 死锁。
TCP 为每一个连接设有一个 持续计时器(persistence timer)。只要 TCP 连接的一方收到对方的零窗口通知,就启动该持续计时器。
若持续计时器设置的时间到期,就发送一个零窗口探测报文段,而对方就在确认这个探测报文段时给出窗口值。
拥塞控制
在某段时间,若对网络中某资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏——产生 拥塞(congestion)。
拥塞控制:防止过多的数据注入到网络中,使网络中的路由器或链路不致过载。是一个全局性的过程,涉及到与降低网络传输性能有关的所有因素。
流量控制:抑制发送端发送数据的速率,以使接收端来得及接收。是点对点通信量的控制,是端到端的问题。
发送方维持一个 拥塞窗口 cwnd(congestion window)。
拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。
(发送窗口 = min [接收窗口,拥塞窗口])
发送方控制拥塞窗口的原则是:只要网络没有出现拥塞,拥塞窗口就再增大一些,以便把更多的报文段发送出去。但只要网络出现拥塞,拥塞窗口就减小一些,以减少注入到网络中的报文段数。
发送方根据超时来预测网络出现拥塞,接收方可以通过发送重复确认来报告拥塞
TCP 进行拥塞控制的算法有 4 种:
- 慢开始 slow start
- 拥塞避免 congestion avoidance
- 快重传 fast retransmit
- 快恢复 fast recovery
慢开始
当主机开始发送数据时,由于并不清楚网络的负荷情况,所以如果立即把大量数据字节注入到网络,那么就有可能引起网络发生拥塞。因此,应由小到大逐渐增大拥塞窗口数值。
初始拥塞窗口cwnd设置为不超过 2 至 4 个 MSS 的数值。
在每收到一个对新的报文段的确认后,拥塞窗口cwnd增加 (min(新被确认的字节数,MSS))字节。
假设发送窗口 = 拥塞窗口,且用报文段的个数作为窗口大小的单位。
每经过一个 传输轮次,拥塞窗口 cwnd 就加倍。
传输轮次(transmission round):把拥塞窗口所允许发送的报文段都连续发送出去,并收到了对已发送的最后一个字节的确认。
当拥塞窗口 cwnd < 慢开始门限 ssthresh 时,使用慢开始算法。
乘法减小:只要出现一次超时(即网络拥塞),就把慢开始门限值 ssthresh 设置为当前的发送窗口值乘以 0.5。当网络频繁出现拥塞时,ssthresh 值就下降得很快,以大大减少注入到网络中的分组数。
拥塞避免
让拥塞窗口 cwnd 缓慢地增大,即每收到一个确认就把发送方的拥塞窗口 cwnd 增加 MSS * MSS / cwnd 字节(一个轮次增加1个MSS),即按线性规律缓慢增长(加法增大),比慢开始算法的拥塞窗口增长速率缓慢得多。
快重传
快重传算法要求接收方每收到一个失序的报文段后就立即发出重复确认。发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段。
快恢复
当发送端收到连续三个重复的确认时,执行乘法减小,把慢开始门限 ssthresh 减半。网络很可能没有发生拥塞,因此拥塞窗口 cwnd 不设置为 1,而是设置为慢开始门限 ssthresh 减半后的数值(或再加 3*MSS),然后开始执行拥塞避免算法,使拥塞窗口缓慢地线性增大。
拥塞控制:
连接建立
- 要使每一方能够确知对方的存在
- 要允许双方协商一些参数(如最大报文段长度,最大窗口大小,服务质量等)
- 能够对传输实体资源(如缓存大小,连接表中的项目等)进行分配
3次握手:
- A 在打算建立 TCP 连接时,向 B 发出连接请求报文段,这时首部中的同步位 SYN=1,同时选择一个初始序号 seq=
x。该报文段不能携带数据,但要消耗掉一个序号。 - B 收到连接请求报文段后,如同意建立连接,则向 A 发送确认。在确认报文段中 SYN 位和 ACK 位都置1,确认号是 ack=x+1,同时也为自己选择一个初始序号 seq=y。
该报文段也不能携带数据,同样要消耗掉一个序号。 - A 收到 B 的确认后,还要向 B 给出确认。确认报文段的 ACK 置1,确认号 ack=y+1,而自己的序号 seq=x+1。ACK 报文段可以携带数据。但如果不携带数据则不消耗序号,在这种情况下,下一个数据报文段的序号仍是 seq=x+1。
A 发出确认的确认(第3次握手)原因:为了防止已失效的连接请求报文段突然又传送到了B,因而产生错误。
A 发出连接请求,但因连接请求报文滞留在网络中而未收到确认。于是 A 再重传一次连接请求。后来收到了确认,建立了连接。
连接释放后滞留的连接请求到达 B。假定不采用报文握手,那么只要 B 发出确认,新的连接就建立了。由于现在 A 并没有发出建立连接的请求,因此不会发送数据。但 B 却以为新的运输连接已经建立了,并一直等待A发来数据。B 的资源就白白浪费了。
连接释放
4次挥手:
- 数据传输结束后,通信的双方都可释放连接。A 停止发送数据,主动关闭连接。连接释放报文段的终止控制位 FIN 置1,其序号 seq=u,u等于前面已传送过的数据的最后一个字节的序号加1。FIN 报文段即使不携带数据,它也消耗掉一个序号。
- B 收到连接释放报文段后即发出确认,确认号是 ack=u+1,而这个报文段自己的序号是 v,等于 B 前面已传送过的数据的最后一个字节的序号加 1。此时从 B 到 A 这个方向的连接并未关闭。 A 收到来自 B 的确认后,等待 B 发出的连接释放报文段。
- B 发出的连接释放报文段必须使 FIN=1。B 的序号为 w。B必须重复上次已发送过的确认号 ack=u+1。这时 B 等待 A 的确认。
- A 在收到 B 的连接释放报文段后,必须对此发出确认。ACK 置1,确认号 ack=w+1,而自己的序号是 seq=u+1。现在 TCP 连接还没有释放掉。必须经过时间等待计时器(TIME-WAIT timer)设置的时间 2MSL(最长报文段寿命) 后,A才进入到 CLOSED 状态。
等待 2MSL 的原因:
- 保证 A 发送的最后一个 ACK 报文段能够到达 B。
- 防止已失效的连接请求报文段出现在本连接中。A 在发送完最后一个 ACK 报文段后,再经过时间 2MSL,就可以使本连接持续的时间内所产生的所有报文段,都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。
有限状态机:
参考资料:《计算机网络》 谢希仁 著
以上是关于计算机网络 —— 运输层的主要内容,如果未能解决你的问题,请参考以下文章