文章目录
传输层概述
网络层知道怎么把数据报传递给一台主机,但不知道怎么把数据报传递给具体的进程,传输层完成的就是这项任务
传输层的功能
提供端到端的逻辑通信
- 运输层向高层用户屏蔽了下面网络核心的细节(如网络拓扑、所采用 的路由选择协议等),它使应用进程看见的就是好像在两个运输层实体之间有一条端到端的逻辑通信信道
复用和分用(通过端口实现)
- “复用” 是指在发送方不同的应用进程都可以使用同一个运输层协议传送数据
- "分用"是指接收方的运输层在剥去报文的首部后能够把这些数据正确交付目的 应用进程
差错检测
- 对首部和数据部分进行差错检测
两种传输协议
- TCP
- UDP
传输层的端口
基本概念
-
虽然通信的终点是应用进程,但只要把所传送的报文交到目的主机的指定目的端口后剩下的工作(即最后交付目的进程)就由TCP或UDP来完成
- 端口是主机为了最终找到通信的进程
-
端口号只具有本地意义,只是为了标志本计算机应用层中的各个进程在和运输层交互时的接口
-
对于一对套接字(ip1,port1)-(ip2,port2),只能存在唯一的TCP连接,后续再建立将会被阻止。
- 但是(ip1,port1)-(ip2,port2)和(ip1,port1)-(ip3,port3)是可以同时存在的,即一个服务器和多个客户端,服务器需要每次选择发数据给那个客户端。
服务器端使用的端口号
-
熟知端口号 [0~1023]
FTP TELNET SMTP DNS TFTP HTTP SNMP 21 23 25 53 69 80 161 -
这里所提到的端口号都是指服务器端的端口号,客户端可自行分配
例如,我的PC像某网址发起一个HTTP请求,是向该网站的服务器的80端口发起一个请求,而我的PC作为客户端,使用的端口号是系统自动分配的(49152~65535)
-
-
登记端口号 [1024~49151]
客户端使用的端口号
49152~65535
套接字
- 在网络中采用发送方和接收方的套接字组合来识别端点,套接字唯一标识了网络中的一个主机和它上面的一个进程
- 套接字 Socket=(主机IP地址,端口号)
用户数据报协议 UDP
概览
在IP的数据报服务之上提供的两个服务
-
复用分用
- 通过端口实现
-
差错检测
- 通过校验
特点
-
无连接,不需要确认,时延小
- 尽最大努力交付,即不保证可靠交付,可靠性由应用程序保证
- 主机不需要维持复杂的连接状态表
- 不需要使用套接字(TCP之间的通信必须要在两个套接字之间建立连接)
-
首部开销小(较TCP)
-
UDP是面向报文的
发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。这就是说,应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。(应用程序必须选择合适大小的报文。报文太长,IP层在要进行分片,会降低IP层的效率。太短,IP数据报的首部的相对长度太大,降低了IP层的效率)
-
UDP没有拥塞控制
因此网络出现的拥塞不会使源主机的发送速率降低。很多实时应用(如IP电话、实时视频会议、游戏等)要求源主机以恒定的速率发送数据,并且允许在网络发生拥塞时丢失一些数据,但却不允许数据有太大的时延。(即UDP适用于时延小,实时性要求较高的情形。)
-
UDP支持单播、广播、组播
- TCP只支持单播
UDP首部格式
字段含义
-
源端口
- 在需要对方回信时选用,不需要时可用全0
-
目的端口
- 终点交付报文时必须使用
- 如果接收方发现不存在对应于端口号的应用进程,那么就丢弃该报文,并由 ICMP 发送“端口不可达”差错报文给发送方。
-
数据报长度
- 最小值是8(仅有首部)
-
检验和
- 检测UDP用户数据报在传输中是否有错,有错就丢弃。
- 校验和段不是必须的,如果不使用填入0(注意,如果计算结果是0,则根据反码应当填入全1)
UDP校验
为什么需要校验?
- 因为IP数据报只检验首部,而UDP用户数据报又是IP数据报的数据部分,所以必须要检验,否则甚至连UDP数据报的端口号是不是正确的
校验哪些部分?
- UDP首部+数据+IP数据报的IP地址
校验步骤
-
发送端
- 填上伪首部
- 全0填充检验和字段
- 全0填充数据部分(UDP数据报要看成许多4B的字串接起来)
- 伪首部+首部+数据部分采用二进制反码求和
- 把和求反码填入检验和字段
- 去掉伪首部,发送
-
接收端
- 填上伪首部
- 伪首部+首部+数据部分采用二进制反码求和(这时的检验和字段是发送端得出的结果)
- 结果全为1则无差错,否则丢弃数据报/交给应用层附上出差错的警告。
传输控制协议 TCP
概览
特点
-
面向连接
- 使用TCP协议之前,必须先建立TCP连接。传送数据完毕后,必须释放已经建立的TCP连接
- TCP连接是一条逻辑连接
-
每一条TCP连接只能是点对点的
- 但允许向一台服务器与多台客户机建立连接
-
提供可靠交付的服务
-
通过TCP连接传送的数据,保证无差错、不丢失、不重复、按序交付(不是"到达")
- IP层每个数据报是要自己选择路由的,肯定无法保证按序到达,乱序到达的会先存在缓存里。
-
-
提供全双工通信
- TCP连接的两端都设置有发送缓存和接收缓存
-
面向字节流
- “流”指的是流入到进程或从进程流出的数据
- 提供的是对报文段的确认
-
时延大,可重传,可靠
- 适用于大文件传输
-
不提供广播或组播服务
套接字
- 在网络中采用发送方和接收方的套接字组合来识别端点,套接字唯一标识了网络中的一个主机和它上面的一个进程
- 套接字 Socket=(主机IP地址,端口号)
- 每一条TCP连接唯一地被通信两端的两个端点(即两个套接字)所确定。
TCP报文段
字段含义
-
源端口号
-
目的端口
-
序号
- TCP是面向字节流的,在一个TCP连接中传送的字节流中的每一个字节都按顺序编号
- 这个序号是每个字节的序号,所以一个TCP报文段的存活时间不能超过发送2^32B字节的时间
-
确认号
- 期望收到对方下一个报文段的第一个数据字节的序号
-
数据偏移
- 即首部长度,长度单位4B
-
保留
- 占6位,保留,必须填0
-
六个控制位
-
紧急 URG
- 当URG=1时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送,不用在(发送方)缓存里排队,配合紧急指针字段使用
- 例如已经建立连接的下载会话,强行中断
-
确认 ACK
- 当ACK=1时,确认号字段有效。TCP规定,在连接建立后所有传送的报文段都必须把ACK置1。
-
推送 PSH
- 接收方TCP收到PSH=1时,(接收方)尽快地交付接收应用进程,而不再等到(接收方)缓存都填满了后再向上交付。
- 虽然应用程序可以选择推送操作,但推送操作很少使用
-
复位 RST
- 当RST=1时,表明TCP连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。
- RST=1还用来拒绝一个非法的报文段或拒绝打开一个连接。
-
同步 SYN
- SYN=1和ACK=0时,表明这是一个连接请求报文
- 对方若同意建立连接,则应在响应的报文段中使SYN=1和ACK=1,即连接接受报文
-
终止 FIN
- 当FIN=1时,表明此报文段的发送方的数据已发送完毕,并要求释放运输连接。
-
-
窗口字段
-
占2字节。窗口指的是发送本报文段的一方的接收窗口(以字节为单位)
- 接收缓存空间还可接收多少个字节数据
-
窗口值作为接收方让发送方设置其发送窗口的依据
-
窗口值经常在动态变化着
- 链路层窗口值是不变的
-
-
检验和
-
紧急指针
- 仅在URG=1时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据放在数据段最前面)因此,紧急指针指出了紧急数据的末尾在报文段中的位置
- 即使窗口为零时也可发送紧急数据
-
选项
- 长度可变,最长可达40字节
-
填充
- 使得TCP首部字段为4B的整数倍
连接管理
连接建立
TCP连接的建立采用客户/服务器方式。主动发起连接建立的应用进程叫做客户,而被动等待连接建立的应用进程叫做服务器。
- 客户端发送连接请求报文段,不可携带数据。
- SYN=1,seq=x(随机)
- 服务器端为该TCP连接分配缓存和变量,并向客户端返回确认报文段,不可携带数据
- SYN=1,ACK=1,seq=y(随机),ack=x+1
- 客户端为该TCP连接分配缓存和变量,并向服务器端返回确认的确认,可以携带数据。(TCP的标准规定,如果不携带数据则不消耗序号,在这种情况下,下一个数据报文段的序号仍是seq=x+1)
- SYN=0, ACK=1, seq=x+1, ack=y+1
为什么A最后还要发送一次确认呢?
- 这主要是为了防止已失效的连接请求报文段突然又传送到了B,因而产生错误。
数据传送
TCP连接已经建立,A进入 ESTABLISHED(已建立连接)状态。当B收到A的确认后,也进入 ESTABLISHED状态。双方可以进行数据传输
连接释放
- 客户端发送连接释放报文段,停止发送数据,主动关闭TCP连接。
- FIN=1, seq=u(前面传送的序号+1)
- 服务器端回送一个确认报文段,客户到服务器这个方向的连接就释放了,TCP连接处于半关闭状态。
- ACK=1,seq=v(前面传送的序号+1),ack=u+1
- 此时B若发送数据,A仍要接收。即B到A方向连接并未关闭,这个状态可能会持续一段时间。
- 服务器端发完数据,就发出连接释放报文段,主动关闭TCP连接。
- FIN=1, ACK=1, seq=w(在半关闭状态B可能又发送了一些数据), ack=u+1(在半关闭状态A一定不会再发送数据了)
- 客户端回送一个确认报文段,再等到时间等待计时器设置的2MSL(最长报文段寿命)后,连接彻底关闭。
- ACK=l, seq=u+l, ack=w+1
第二次时,如果B没有数据要发给A了的话,第二次和第三次是可以合在一起的。也就是说关闭连接最少需要1.5个RTT
可靠传输
校验
- 同UDP
序号、确认
- 对每个报文段进行确认,返回一个ACK报文
- 捎带确认
- 选择确认
- 累计确认
重传
超时重传
- TCP的发送方在规定的时间内没有收到确认就要重传已发送的报文段。TCP采用自适应算法,动态改变重传时间RTTs(加权平均往返时间)
自适应RTTs(超时重传时间的选择)
- TCP采用了一种自适应算法,它记录一个报文段发出的时间,以及收到相应的确认的时间。这两个时间之差就是报文段的往返时间RTT。TCP保留了RTT的一个加权平均往返时间RTTs(Smoothed),a是一个给定的权值。
新的RTTs=(1-a)×(旧的RTTs)+a×(新的RTT样本)
冗余重传/快速重传
- 每当比期望序号大的失序报文段到达时,发送一个冗余ACK,指明下一个期待字节的序号。
- 发送方收到3个冗余ACK(3个冗余,算上最开始丢失的ACK,就是4个),则认为该报文段(ACK指明序号的报文段)丢失,重传报文段
流量控制
- 在通信过程中,接收方根据自己接收缓存的大小,动态地调整发送方的发送窗口大小,这称为接收窗口rwnd,即调整TCP报文段首部中的“窗口”字段值,来限制发送方向网络注入报文的速率。同时,发送方根据其对当前网络拥塞程序的估计而确定的窗口值,这称为拥塞窗口cwnd ,其大小与网络的带宽和时延密切相关。
- 即发送方的发送窗口取接收方的接收窗口rwnd和拥塞窗口cwnd的最小值。注意,TCP的窗口(UDP不具有流量/拥塞控制)单位是字节,不是报文段。更准确的说法是TCP的窗口的单位是MSS(TCP报文段中的数据字段的最大长度),初始cwnd设置为2至4个(新标准,旧标准为1~2个,不说就默认一个)发送方的最大报文段MSS的数值
如果B向A发送了零窗口的报文段后不久,B的接收缓存有了空闲。于是B向A发送了rwnd=400的报文段。然而这个报文段丢失了。A一直等待收到B发送的非零窗口的通知,而B也一直等待A发送的数据,造成死锁局面。
- 为了解决这个问题,TCP为每一个连接设有一个持续计时器。只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器。若持续计时器设置的时间到期,就发送一个零窗口探测报文段(仅携带1字节的数据),而对方就在确认这个探测报文段时给出了现在的窗口值。如果窗口仍然是零,那么收到这个报文段的一方就重新设置持续计时器。如果窗口不是零,那么死锁的僵局就可以打破了。
如果滑动窗口(send和rwnd)设置的过小,则会产生过多的ACK(因为窗口大可以累计确认,ACK会少一些);如果设置的太大,又会导致传送的数据过多而使得路由器变得拥挤,导致主机丢失分组
拥塞控制
为什么会拥塞?
- 若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络吞吐量将随输入负荷增大而下降。即发生了拥塞
- 拥塞常常趋于恶化。如果一个路由器没有足够的缓存空间,当丢弃了一些分组时,源点就会重,甚至可能重传多次,这样会引起更多的分组流入网络和被网络中的路由器丢弃。拥塞引起的重传会加剧网络的拥塞。
拥塞控制与流量控制
- 流量控制是端到端的问题(接收端控制发送端),抑制发送端的发送数据的速率,以便使接收端来得及接收。拥塞控制是一个全局性的过程,防止过多的数据注入到网络中
- 滑动窗口机制实现了端到端的流量控制,而对全局主机的流量控制实现了拥塞控制
传输控制协议 TCP
-
接收窗口rwnd
- 接收方根据接受缓存设置的值,并告知给发送方,反映接收方容量
-
拥塞窗口cwnd
- 发送方根据自己估算的网络拥塞程度而设置的窗口值,反映网络当前容量
-
当rwnd<cwnd时,是接收方的接收能力限制发送方窗口的最大值。当cwnd<rwnd时,则是网络的拥塞程度限制发送方窗口的最大值。
拥塞控制四种算法
一点问题
端到端通信&点到点通信的区别
- 从本质上说,由物理层、数据链路层和网络层组成的通信子网为网络环境中的主机提供点到点的服务,而传输层为网络中的主机提供端到端的通信
- 直接相连的结点之间的通信称为点到点通信,它只提供一台机器到另一台机器之间的通信,不涉及程序或进程的概念。同时点到点通信不保证数据传输的可靠性,也不能说明源主机与目的主机之间是哪两个进程在通信,这些工作都是由传输层来完成的,端到端通信建立在点到点通信的基础上,它是由一段段的点到点通信信道构成的,是比点到点通信更高一级的通信方式,以完成应用程序(进程)之间的通信。“端”是指用户程序的端口,端口号标识了应用层中不同的进程。
IP 数据报和 UDP 数据报的区别
- IP 数据报在网络层要经过路由的存储转发; 而 UDP 数据报在传输层的端到端的逻辑信道中传输,封装成 IP 数据报在网络层传输时,UDP 数据报的信息对路由是不可见的
TCP 和网络层虚电路的区别
- TCP 报文段在传输层抽象的逻辑信道中传输,对路由器不可见; 虚电路所经过的交换结点都必须保存虚电路状态信息。
- 在网络层若采用虚电路方式,则传输层无法提供无连接服务; 而传输层采用 TCP 不影响网络层提供稅连接服务
TCP使用的是GBN还是选择重传?
- TCP使用累计确认,看起来像是GBN,但是正确收到但失序的报文不会丢弃,而是缓存起来,并且发送冗余ACK指明期望收到的下一个报文段,这是TCP方式和GBN的显著区别。另外,TCP中提供一个选择确认选项,看起来又和SR非常相似。因此,TCP的差错恢复可视为GBN和SR协议的混合体。
假定在一个互联网中,所有链路的传输都不出现差错,所有结点也都不会发生故障。试问在这种情况下,TCP的“可靠交付”的功能是否就是多余的?
不是多余的。TCP的“可靠交付”功能在互联网中起着至关重要的作用。在以下的情況下,TCP的“可靠交付”功能是必不可少的。
- 每个IP数据报独立地选择路由,因此在到达目的主机时有可能出现失序
- 由于路由选择的计算出现错误,导致IP数据报在互联网中转圈。
- 某个路由器突然出现很大的通信量,以致路由器来不及处理到达的数据报。因此有的数据报被丢弃。
拥塞控制中为什么超时时间发生时cwnd被置为1,而收到3个冗余ACK时cwnd减半?
**注意,**发生拥塞/超时一定是【慢开始】来处理,【快恢复】处理的是冗余确认,然后都会执行拥塞避免
在收到3个冗余ACK的情况下,网络虽然拥塞,但至少还有ACK 报文段能被正确交付。而当超时发生时,说明网络可能已经拥塞得连ACK报文段都传输不了, 发送方只能等待超时后重传数据。因此,超时事件发生时,网络拥塞更严重,那么发送方就应该最大限度地抑制数据发送量,所以cwnd置为1;收到3个冗余ACK时,网络拥塞不是很严重发送方稍微抑制一下发送的数据量即可,所以cwnd减半。
一点探究
SYN洪泛攻击
- 利用了“服务器端的资源是在第二次握手完成时分配的”
- TCP SYN泛洪发生在OSI第四层,这种方式利用TCP协议的特性,就是三次握手。攻击者发送TCP SYN,SYN是TCP三次握手中的第一个数据包,而当服务器返回ACK后,该攻击者就不对其进行再确认,那这个TCP连接就处于挂起状态,也就是所谓的半连接状态,服务器收不到再确认的话,还会重复发送ACK给攻击者。这样更加会浪费服务器的资源。攻击者就对服务器发送非常大量的这种TCP连接,由于每一个都没法完成三次握手,所以在服务器上,这些TCP连接会因为挂起状态而消耗CPU和内存,最后服务器可能死机,就无法为正常用户提供服务了。这就形成了DoS(Denial of Service拒绝服务)攻击。这种攻击方式就称为SYN泛洪(SYN flood)攻击。
- 对于SYN泛洪攻击的防范,优化主机系统设置是常用的手段。如降低SYN timeout时间,使得主机尽快释放半连接的占用;又比如采用SYN cookie设置,如果短时间内连续收到某个IP的重复SYN请求,则认为受到了该IP的攻击,丢弃来自该IP的后续请求报文。此外合理地采用防火墙等外部网络安全设施也可缓解SYN泛洪攻击。