计算机网络-传输层
传输层
1 传输层的定义
TCP/IP中有两个具有代表性的传输层协议,它们分别是TCP和UDP。TCP在传输层提供可靠的通信传输,而UDP在传输层不提供可靠传输,而是尽最大能力传输,常被用于让广播和细节控制交给应用的通信传输。总之,根据通信的具体特征,选择合适的传输层协议是非常重要的。
在网络层提到在IP的首部有一个协议字段,来标识网络层上一层采用的是哪一种传输层协议,这里我们使用WireShark抓取网络数据包,可以看到Protocol:UDP(17),说明这个数据包是使用UDP协议传输。

TCP是面向连接的、可靠的流协议。流就是指不间断的数据结构,你可以把它想象成排水管道中的水流。当应用程序采用TCP发送消息时,虽然可以保证发送的顺序,但还是犹如没有任何间隔的数据流发送给接收端TCP为提供可靠性传输,实行”顺序控制”或”重发控制”机制。此外还具备”流控制(流量控制)”、”拥塞控制”、提高网络利用率等众多功能。
UDP是不具有可靠性的数据报协议。细微的处理它会交给上层的应用去完成。在UDP的情况下,虽然可以确保发送消息的大小,却不能保证消息一定会到达。因此,应用有时会根据自己的需要进行重发处理。
1.1 端口的定义
在网络层是主机到主机的通信传输,那么到了传输层就是端到端的通信传输,这个端可以可以理解为“逻辑端口”,这个端口并不实际存在,而是我们给主机里面的进程赋予的一段数字,通过端口号,可以准确的找到发送和接收数据的应用(进程)。
数据链路和IP中的地址,分别指的是MAC地址和IP地址。前者用来识别同一链路中不同的计算机,后者用来识别TCP/IP网络中互连的主机和路由器。在传输层中这种类似于地址的概念,那就是端口号。端口号用来识别同一台计算机中进行通信的不同应用程序。因此,它也被称为程序地址。
当然仅仅有端口是不够的,我们还需要更加详细的“位置信息”。通常来说,会使用5个信息来识别一个通信,“源IP地址”、”目标IP地址”、”协议号”、”源端口号”、”目标端口号”,5个信息都一致,才认为是同一个通信。
端口号的长度为16bit,最大可以表示65536个不同的端口号。
1.2 端口号的区分
服务端使用的端口号范围:049151 ,其中01023属于知名端口号,固定下来给应用协议使用,知名端口号一般由0到1023的数字分配,应用程序应该避免使用知名端口号进行既定目的之外的通信,以免产生冲突。1024~49151就是我们可以给自己的服务进程注册的端口号了。
客户端使用的端口号范围:49152~65535。和服务端不同,客户端采用了动态分配法,由于这类端口号仅在客户进程运行时才动态地选择,因此又称短暂端口号(也称临时端口)。通信结束后,刚用过的客户端口号就不复存在,从而这个端口号就可供其他客户进程以后使用。
应用程序 | FTP | TELNET | SMTP | DNS | TFTP | HTTP | SNMP |
---|---|---|---|---|---|---|---|
熟知端口号 | 21 | 23 | 25 | 53 | 69 | 80 | 161 |
2.UDP
2.1 UDP的特点和目的
UDP是UserDatagramProtocol的缩写。
UDP不提供复杂的控制机制,利用IP提供面向无连接的通信服务。并且它是将应用程序发来的数据在收到的那一刻,立即按照原样发送到网络上的一种机制。即使是出现网络拥堵的情况下,UDP也无法进行流量控制等避免网络拥塞的行为。此外,传输途中即使出现丢包,UDP也不负责重发。甚至当出现包的到达顺序乱掉时也没有纠正的功能。如果需要这些细节控制,那么不得不交由采用UDP的应用程序去处理。UDP有点类似于用户说什么听什么的机制,但是需要用户充分考虑好上层协议类型并制作相应的应用程序。因同此,也可以说,UDP按照”制作程序的那些用户的指示行事”。
由于UDP面向无连接,它可以随时发送数据。再加上UDP本身的处理既简单又高效,因此经常用于以下几个方面:
- 包总量较少的通信(DNS、SNMP等)
- 视频、音频等多媒体通信(即时通信)
- 限定于LAN等特定网络中的应用通信
- 广播通信(广播、多播)
总结一下:UDP具有如下特点:
- UDP是无连接的,减少开销和发送数据之前的时延。
- UDP使用最大努力交付,即不保证可靠交付。
- UDP是面向报文的,适合一次性传输少量数据的网络应用,
- UDP无拥塞控制,适合很多实时应用。
- 分组首部开销小。TCP有20B的首部开销,而UDP仅有8B的开销。
- UDP支持一对一、一对多、多对一和多对多的交互通信。
2.2 UDP报文格式
UDP数据报包含两部分:UDP首部和用户数据。UDP首部和用户数据。UDP首部有8B,由4个字段组成,每个字段的长度都是2B。

源端口:源端口号。在需要对方回信时选用,不需要时可用全0。
目的端口:目的端口号。这在终点交付报文时必须使用到。
长度:单位字节,UDP数据报的长度(包括首部和数据),其最小值是8(仅有首部)。
校验和:检测UDP数据报在传输中是否有错。有错就丢弃。该字段是可选的,当源主机不想计算校验和时,则直接令该字段为全0。
在计算校检和时,要在UDP用户数据报之前增加12字节的****伪首部****。校检和就是按照这个临时的UDP用户数据报来计算的。这个伪首部的作用就是计算校验和,它既向上传递也不向下封装。

扩展:UDP的校验和计算
UDP校验和的计算方法和IP数据报首部校验和的计算方法相似。但不同的是,IP数据报的校验和只检验IP数据报的首部,但UDP的校验和则检查首部和数据部分。
发送方首先把全零放入校验和字段并添加伪首部,然后把UDP数据报视为许多16位的字串接起来。
若UDP数据报的数据部分不是偶数个字节,则要在数据部分末尾填入一个全零字节(但此字节不发送)。
然后按二进制反码计算出这些16位字的和,将此和的二进制反码写入校验和字段,并发送。
接收方把收到的UDP数据报加上伪首部(如果不为偶数个字节,那么还需要补上全零字节)后,按二进制反码求这些16位字的和。
当无差错时其结果应为全1,否则就表明有差错出现,接收方就应该丢弃这个UDP数据报。
计算UDP检验和的例子:
![]()
二进制反码运算求和:将所有的字相加,如果相加过程中最高位产生了进位,就将进位加到最低位上,这叫做回卷。
3.TCP
3.1TCP协议的特点和目的
为了通过IP数据报实现可靠性传输,需要考虑很多事情,例如数据的破坏丢包、重复以及分片顺序混乱等问题。如不能解决这些问题,也就无从谈起可靠传输。
TCP通过检验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输。
TCP的任务是在IP层不可靠的、尽力而为服务的基础上建立一种可靠数据传输服务。
主要特点如下:
TCP是面向连接(虚连接)的传输层协议
每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的
TCP 提供可靠交付的服务,保证传送的数据无差错、不丢失、不重复且有序
TCP提供全双工通信,两端都有发送缓存和接受缓存。
发送缓存用来暂时存放以下数据:①发送应用程序传送给发送方TCP准备发送的数据;②TCP已发送但尚未收到确认的数据。
接收缓存用来暂时存放以下数据:①按序到达但尚未被接收应用程序读取的数据;②不按序到达的数据。
TCP是面向字节流的。虽然应用程序和TCP的交互是一次一个数据块(大小不等),但TCP把应用程序交下来的数据仅仅看成是一连串的无结构的字节流。
3.2TCP的报文段
TCP传送的数据单元称为报文段。TCP报文段既可以用来运载数据,又可以用来建立连接、释放连接和应答。
一个TCP报文段分为首部和数据两部分,整个TCP报文段作为IP数据报的数据部分封装在IP数据报中,其首部的前20B是固定的。TCP首部最短为20B,后面有4N字节是根据需要而增加的选项,长度为4B的整数倍。

源端口和目的端口:各占2字节,分别写入源端口号和目的端口号
序号:占4个字节,TCP是面向字节流的传输,里面的每一个字节都会进行编号,该字段表示本报文段所发送数据的第一个字节的序号。
确认号:占4个字节,期望收到对方下一个报文段的第一个数据字节的序号,若确认号为N,则表示到N-1为止的所有的数据都已经正确收到。
数据偏移:也就是首部长度。占4个bit,TCP报文段的数据的起始位置距离TCP报文段的起始位置由多远,一个数值的单位是4B,4位二进制数能够表示的最大十进制数字是15,那么数据偏移的最大值为60字节。TCP首部的最大长度:60字节。选项部分的最大长度:40字节。
保留:占6位,保留为今后使用,但目前应置为0。
控制位:占6位。
- 紧急位URG:URG=1时,标明此报文段中有紧急数据,是高优先级的数据,应尽快传送,不用在缓存里排队,配合紧急指针字段使用。
- 确认位ACK:ACK=1时确认号有效,在连接建立后所有传送的报文段都必须把ACK置为1。
- 推送位PSH:PSH=1时,接收方尽快交付接收应用进程,不再等到缓存填满再向上交付。
- 复位RST:RST=1时,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立传输链接。
- 同步位SYN:SYN=1时,表明是一个连接请求/连接接受报文。
- 终止位FIN:FIN=1时,表明此报文段发送方数据已发完,要求释放连接
窗口:指的是发送本报文段的一方的接收窗口,即现在允许对方发送的数据量。
检验和:检验首部+数据,检验时要加上12B伪首部,第四个字段为6。(UDP是17)
紧急指针:URG=1时才有意义,指出本报文段中紧急数据的字节数(紧急数据在报文段数据的最前面)。
选项:长度可变。最大报文段长度MSS、窗口扩大、时间戳、选择确认。
填充:这是为了使整个首部长度是4B的整数倍。
3.3 TCP可靠传输
什么是可靠?
可靠,指的是保证接收方进程从缓存区读出的字节流与发送方发出的字节流是完全一样的。
3.3.1 通过序列号与确认应答提高可靠性
在TCP中,当发送端的数据到达接收主机时,接收端主机会返回一个已收到消息的通知。这个消息叫做确认应答(ACK)。在一定时间内没有等到确认应答,发送端就可以认为数据已经丢失,并进行重发。由此,即使产生了丢包,仍然能够保证数据能够到达对端,实现可靠传输。
通过ACK确认的方式,保证服务端能收到客户端发送的每一个报文段。
TCP通过肯定的确认应答(ACK)实现可靠的数据传输。当发送端将数据发出之后会等待对端的确认应答。如果有确认应答,说明数据已经成功到达对端。反之,则数据丢失的可能性很大。
为什么是可能是数据丢失?因为存在服务端已经收到了数据并且发送了ACK,但是客户端没有收到,这时候客户端会误认为丢失,重新发送相同的数据。也有可能因为通信问题导致ACK延迟到达,在源主机重发数次之后才姗姗来迟,这种情况对于目标主机来说,简直是一场灾难,因为要对上层应用提供可靠的传输,必须得放弃重复的数据包,这造成了资源的极大浪费。
为了解决上述的问题,TCP再次引入了序列号的机制。给每一字节的数据都进行编号。接收端查询接收数据TCP首部中的序列号和数据的长度,将自己下一步应该接收的序号作为确认应答返送回去。就这样,通过序列号和确认应答号,TCP可以实现可靠传输。


3.3.2重发超时如何确定
有两种事件会导致TCP对报文段进行重传:超时和冗余ACK。
- 超时重传
TCP每发送一个报文段,就对这个报文段设置一次计时器。只要计时器设置的重传时间到期但还没有收到确认,就要重传这一报文段。TCP采用自适应算法,动态改变重传时间RTTs(加权平均往返时间)
- 冗余ACK(冗余确认)
TCP规定每当比期望序号大的失序报文段到达时,发送一个冗余ACK,指明下一个期待字节的序号。当发送方收到对同一个报文段的3个冗余ACK时,就可以认为跟在这个被确认报丈段之后的报文段已经丢失。
发送方已发送1,2,3,4,5报文段
接收方收到1,返回给1的确认(确认号为2的第一个字节)
接收方收到3,仍返回给1的确认(确认号为2的第一个字节)
接收方收到4,仍返回给1的确认(确认号为2的第一个字节)
接收方收到5,仍返回给1的确认(确认号为2的第一个字节)
发送方收到3个对于报文段1的冗余ACK,认为2报文段丢失,重传2号报文段。
3.4TCP的连接管理
TCP是面向连接的协议,因此每个TCP连接都有三个阶段:连接建立、数据传送和连接释放。可以使用TCP首部用于控制的字段来管理TCP连接 。一个连接的建立与断开,正常过程至少需要来回发送7个包才能完成。
3.4.1三次握手建立连接
客户向服务器发送连接请求段,建立连接请求控制段(SYN=1),表示传输的报文段的第一个数据字节的序列号是x,此序列号代表整个报文段的序号(seq=x);客户端进入 SYN_SEND (同步发送状态);
服务器发回确认报文段,同意建立新连接的确认段(SYN=1),确认序号字段有效(ACK=1),服务器告诉客户端报文段序号是y(seq=y),表示服务器已经收到客户端序号为x的报文段,准备接受客户端序列号为x+1的报文段(ack_seq=x+1);服务器由LISTEN进入SYN_RCVD (同步收到状态);
客户对服务器的同一连接进行确认.确认序号字段有效(ACK=1),客户此次的报文段的序列号是x+1(seq=x+1),客户期望接受服务器序列号为y+1的报文段(ack_seq=y+1);当客户发送ack时,客户端进入ESTABLISHED 状态;当服务收到客户发送的ack后,也进入ESTABLISHED状态;第三次握手可携带数据;

细节问题:
为什么要第三次确认?
是为了防止失效的连接请求又传送到了服务端,导致出现错误。防止第一次发送的连接请求报文段滞后到达,A在接收到B的确认就开始传送数据,而B确以为建立了新的连接而无法接收,导致数据丢失。
什么是SYN洪范攻击?
SYN洪泛攻击的原理和过程如下:
- 攻击者向服务器发送大量的SYN数据包,请求建立连接,但是故意伪造或随机生成源IP地址,使服务器无法回复。
- 服务器收到SYN数据包后,回复SYN-ACK数据包,并为每个连接分配一个缓冲区,等待客户端的ACK数据包,进入SYN-RCVD状态。
- 由于源IP地址是伪造或随机的,服务器无法收到客户端的ACK数据包,导致缓冲区被占用,无法处理其他的连接请求。
- 当缓冲区满了后,服务器就无法接受新的连接请求,从而拒绝服务。
解决办法:设置SYN cookie,即在回复SYN-ACK数据包时,不分配缓冲区,而是将一些信息编码在序列号中,等到收到ACK数据包时再解码恢复。
3.4.2四次挥手断开连接
客户向服务器发送释放连接报文段,发送端数据发送完毕,请求释放连接(FIN=1),传输的第一个数据字节的序号是x(seq=x,它等于前面已传送过的数据的最后一个字节的序号加1);客户端状态由ESTABLISHED进入FIN_WAIT_1(终止等待1状态);
服务器向客户发送确认段,确认字号段有效(ACK=1),服务器传输的数据序号是y(seq=y),服务器期望接收客户数据序号为x+1(ack_seq=x+1);服务器状态由ESTABLISHED进入CLOSE_WAIT(关闭等待); 客户端收到ACK段后,由FIN_WAIT_1进入FIN_WAIT_2;
服务器若发送数据,客户机仍要接收,即从服务器到客户机这个方向的连接并未关闭。
服务器向客户发送释放连接报文段,请求释放连接(FIN=1),确认字号段有效(ACK=1),表示服务器期望接收客户数据序号为x+1(ack_seq=x+1);表示自己传输的第一个字节序号是y+1(seq=y+1);服务器状态由CLOSE_WAIT 进入 LAST_ACK (最后确认状态);
客户向服务器发送确认段,确认字号段有效(ACK=1),表示客户传输的数据序号是x+1(seq=x+1),表示客户期望接收服务器数据序号为y+1+1(ack_seq=y+1+1);客户端状态由FIN_WAIT_2进入TIME_WAIT,等待2MSL时间,进入CLOSED状态;服务器在收到最后一次ACK后,由LAST_ACK进入CLOSED;

细节问题:
为什么A在TIME-WAIT状态必须等待2MSL的时间呢?
第一,为了保证A发送的最后一个ACK报文段能够到达B。
第二,防止“已失效的连接请求报文段”出现在本连接中。

3.5 TCP的流量控制
TCP提供流量控制服务来消除发送方(发送速率太快)使接收方缓存区溢出的可能性。TCP提供一种基于滑动窗口协议的流量控制机制。
滑动窗口:
- 接收窗口rwnd:接收端维护,接收端当前的接收缓存大小。
- 拥塞窗口cwnd:发送端维护,发送端根据当前网络的拥塞程度而确定的窗口值。
- 发送窗口:由发送端维护,发送端在接收到下一个确认前能够发送的最大字节数。
- 发送窗口=min(接收窗口,拥塞窗口)
在通信过程中,接收方根据自己接收缓存的大小,动态地调整发送方的发送窗口大小,即接收窗口rwnd(接收方设置确认报文段的窗口字段来将rwnd通知给发送方),
发送方的发送窗口取接收窗口rwnd和拥塞窗口cwnd的最小值。TCP的窗口单位是字节,不是报文段。

如上图所示,设A向B发送数据。在连接建立时,B的接收窗口rwnd=400。接收方主机B进行了三次流量控制,这三个报文段都设置了ACK=1,只有在ACK=1时确认号字段才有意义。第一次把窗口减小到rwnd=300,第二次又减到rwnd=100,最后减到rwnd=0,即不允许发送方再发送数据。这使得发送方暂停发送的状态将持续到B重新发出一个新的窗口值为止。
传输层和数据链路层的流量控制的区别是:
传输层定义端到端用户之间的流量控制,数据链路层定义两个中间的相邻结点的流量控制。
数据链路层的滑动窗口协议的窗口大小不能动态变化,传输层的则可以动态变化。
3.6TCP的拥塞控制
拥塞控制是指防止过多的数据注入网络,保证网络中的路由器或链路不致过载,是全局性过程。出现拥塞时,端点并不了解拥塞发生的细节,对通信连接的端点来说,拥塞往往表现为通信时延的增加。
$$
发送窗口的上限值=min[rwnd,cwnd]
$$
因特网建议标准定义了进行拥塞控制的4种算法:慢开始、拥塞避免、快重传和快恢复。
3.6.1.慢开始和拥塞避免
慢开始:
- 先令拥塞窗口cwnd=1(即一个最大报文段长度MSS)。
- 在每收到一个对新的报文段的确认后,将cwnd加1,即增大一个MSS(拥塞窗口加倍)。
拥塞避免:
- 发送端的拥塞窗口cwnd每经过一个往返时延RTT就增加一个MSS的大小,而不是加倍,使cwnd按线性规律缓慢增长(即加法增大)
- 当出现一次超时(网络拥塞)时,则令慢开始门限ssthresh等于当前cwnd的一半(即乘法减小)
根据cwnd的大小执行不同的算法,可归纳如下:
- 当cwnd<ssthresh时,使用慢开始算法。
- 当cwnd>ssthresh时,停止使用慢开始算法而改用拥塞避免算法。
- 当cwnd=ssthresh时,既可使用慢开始算法,又可使用拥塞避免算法(通常做法)。
网络拥塞处理

① 执行慢开始算法,拥塞窗口cwnd置为1,每收到一个ACK,cwnd加1,即每个轮次拥塞窗口翻倍。
② 达到ssthresh初始值16,执行拥塞避免算法,每个轮次拥塞窗口加1。
③ 在cwnd达到24时,出现超时,发送方判断网络拥塞;调整门限ssthresh为12,cwnd置1,重新慢开始。当拥塞窗口到达12时,开始执行拥塞避免。
当网络出现拥塞时,无论在什么阶段,只要发送方检测到超时事件的发生(没有按时收到确认。重传计时器超时),就要把慢开始门限ssthresh设置为出现拥塞时的发送方cwnd值的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。
3.6.2 快重传和快恢复
快重传和快恢复算法是对慢开始和拥塞避免算法的改进。
- 快重传:收到3个重复的确认执行快重传算法。
- 快恢复:当发送端收到连续三个冗余ACK时,就执行“乘法减小”算法,把慢开始门限ssthresh设置为出现拥塞时发送方cwnd的一半。与慢开始(将拥塞窗口cwnd设置为1)不同之处是它把cwnd的值设置为慢开始门限ssthresh改变后的数值,然后开始执行拥塞避免算法(加法增大),使拥塞窗口缓慢地线性增大。

在流量控制中,发送方发送数据的量由接收方决定,而在拥塞控制中,则由发送方自己通过检测网络状况来决定。实际上,慢开始、拥塞避免、快重传和快恢复几种算法是同时应用在拥塞控制机制中。
四种算法使用的总结:
- 在TCP连接建立和网络出现超时时,采用慢开始和拥塞避免算法;
- 当发送方接收到冗余ACK时,采用快重传和快恢复算法。
实践:
[Wireshark 分析用户数据报UDP](Wireshark 分析用户数据报UDP_wiresharkudp报文分析-CSDN博客)