5.运输层
5.1 概述
- 之前的物理层、数据链路层以及网络层它们共同解决了主机通过异构网络互联所面临的问题,实现了主机到主机的通信。但实际上计算机网络中的通信时位于通信两段主机中的进程。
运输层任务:为运行在不同主机上的应用进程提供直接的通信服务。运输层协议又称端到端协议。
因特网的运输层为应用层提供了两种不同的运输协议,即面向连接的TCP和无连接的UDP。
5.2 端口号、复用与分用
- 运行在计算机上的进程用进程标识符PID来标志,到那时不同操作系统使用不同格式的进程标识符,因此需要用统一的方法对TCP/IP体系的应用进程进行标识。
- TCP/IP体系的运输层使用端口号来区分应用层的不同应用进程。
端口号用16比特标识,取值范围0-65535。其中,熟知端口号:0-1023,用于TCP/IP体系中最重要的一些应用协议,例如FTP使用21/20,HTTP使用80,DNS使用53;登记端口号:1024-49151;短暂端口号:49152-65535,留给客户进程选择暂时使用。
端口号只具有本地意义,只是为了标识本计算机应用层中的各进程,在因特网中,不同计算机中的相同端口号是没有联系的。
- 发送方的复用和接收方的分用:

- 运输层熟知端口号:

5.3 UDP和TCP的对比

UDP支持单播、多播以及广播,也就是支持一对一,一对多,多对一和多对多交互通信;TCP仅支持单播,也就是只能一对一通信。
UDP是面向应用报文的;TCP是面向字节流的。
- UDP向上层提供无连接不可靠传输服务(适用于IP电话、视频会议等实时应用);TCP向上层提供面向连接的可靠传输服务(适用于要求可靠传输的应用,例如文件传输)。
- UDP用户数据报首部仅8字节;TCP报文段首部最小20字节,最大60字节。
5.4 TCP的流量控制
- 一般来说,我们希望数据发的更快一些,但是如果发送方的数据发送的过快,接收方就可能来不及接收,就会造成数据的丢失。所以要进行流量控制,让发送方的发送速率不要太快,要让接收方来得及接收。利用滑动窗口机制可以实现流量控制。


5.5 TCP的拥塞控制
- 在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就要变坏,这种情况就叫做拥塞。
- 有四种基本拥塞控制算法,细节略去:慢开始、拥塞避免、快重传、快恢复。
5.6 TCP超时重传时间的选择
- 超时重传时间不能太久也不能太短,一般应该略大于往返时间。
- 如何设置超时重传时间?一般根据往返时间计算得出,是有公式的,并且随着时间的变化超时重传时间计算出来也是不一样的,具体怎么计算的细节略去。
5.7 TCP可靠传输的实现
- TCP基于以字节为单位的滑动窗口来实现可靠传输。
发送方和接收方均设置滑动窗口,并且分别设置窗口大小。发送方滑动窗口内的字节代表可以发送,接收方滑动窗口内的字节代表可以接收。
接收方必须有累计确认和捎带确认机制。
TCP的通信是全双工通信。
5.8 TCP的运输连接管理
- TCP是面向连接的协议,它基于运输连接来传送TCP报文段。
- TCP运输连接的建立和释放是每一次面向连接的通信中必不可少的过程。
- TCP的运输连接有三个阶段:1.建立TCP连接 2.数据传送 3.释放TCP连接
- TCP的运输连接管理就是使运输连接的建立和释放都能正常地运行。
5.8.1 TCP的连接建立—三次握手
- 连接建立主要解决三个问题:1.使TCP双方能够确知对方的存在;2.使TCP双方能够协商一些参数;3.使TCP双方能够对运输实体资源进行分配。
- 三次握手过程:

第一次握手:客户端向服务器发送TCP连接数据报,代表客户端想要建立连接,其中要将SYN设置为1,代表是在建立连接,并且将seq初始化一个x值。
第二次握手:服务器像客户端发送TCP连接数据报,代表服务器想要建立连接,其中将SYN设置为1,代表是在建立连接;将ACK设为1代表数据报中含有ack;将seq初始化一个y值,将ack设置为x+1。
第三次握手:客户端像服务器发送TCP普通数据报,代表服务器的TCP连接数据报已收到,其中ACK为1,代表存在ack,将seq设置为x+1,ack设置为y+1。
- 能不能取消第三次握手,只采用两次握手?
当然是不能的,不然大家就说两次握手不说三次握手了(啊不是)。确实是不能,但是为啥不能?
现在假设我们只采用两次握手,那么考虑下图这种情况:

假设第一次握手由于网络原因很久才会到达服务器,而在它到达之前,客户端已经重发了第一次握手并且已经和服务器完成了连接建立,完成了数据传输,完成了释放连接,一切都已经结束。这时,服务器收到了原本的第一次握手,这时服务器向客户端发起第二次握手,但是由于客户端已经关闭了不会理睬,那么服务器就会一直向客户端发送第二次握手,实在是浪费资源。(服务器属实是舔🐶了)。
5.8.2 TCP的连接释放—四次挥手

第一次挥手:客户端发送TCP释放连接数据报,代表客户端没有数据要向服务器发送了,其中将FIN位设置为1,代表是释放连接;将ACK设置为1,代表存在ack;将seq设置为u,将ack设置为v。
第二次挥手:服务器发送TCP普通数据报,代表服务器收到客户端的释放连接数据报,其中将ACK设置为1,代表存在ack;将seq设置为v,将ack设置为u+1。
在这中间,如果服务器还有数据要发送给客户端,那么将继续发送给客户端,奉献自己最后的一点爱。
第三次挥手:服务器发送TCP释放连接数据报,代表服务器没有数据要向服务器发送了,其中将FIN位设置为1,代表是释放连接;将ACK设置为1,代表存在ack;将seq设置为w,将ack设置为u+1。
第四次挥手:客户端发送TCP普通数据报,代表客户端收到服务器的释放连接数据报,其中将ACK设置为1,代表存在ack;将seq设置为u+1,将ack设置为w+1。
在服务器接收到第四次挥手后就关闭连接,而客户端等待2MSL时间后也关闭连接。
- 为什么客户端要等待2MSL时间后在关闭连接?可不可以不等待,在发出第四次挥手后就立刻关闭呢?
不行。假设客户端立刻关闭连接的话,假如客户端发起的第四次挥手丢失了, 那么服务器由于舔🐶属性(啊不是)会一直等待客户端的第四次挥手,如果等不到,就会反复地向客户端发送第三次挥手,但是由于客户端已关闭,无法相应服务器的第三次挥手,就无法进入关闭状态。所以当客户端等待2MSL时间,在这个时间段内如果收到服务器的第三次挥手就会重发第四次挥手。
- 当客户端出现故障时,服务器端如何才能知道呢?
TCP服务器进程没收到一次TCP客户端进程的数据,就重新设置并启动保活计时器(2小时定时)。
若保活计时器定时周期内未收到TCP客户端发来的数据,则当保活计时器到时后,TCP服务器进程就向TCP客户进程发送一个探测报文段,以后则每个75秒钟发送一次。若一连发送10个探测报文段后仍无TCP客户端进程的响应,TCP服务器进程就认为TCP客户进程所在主机出了故障,接着就关闭这个连接。
5.9 TCP报文段的首部格式
