运输层
概述
计算机网络体系中的物理层,数据链路层以及网络层共同解决了将主机通过异构网络互联起来所面临的的问题,实现了主机到主机间的通信
实际上在计算机网络中进行通信的真正实体是位于通信两端主机中的进程
如何为运行在不同主机上的引用进程提供直接通信服务是运输层的任务,运输层协议又称为端对端协议
端口可以说是进程的标识符
运输层直接为应用进程间的逻辑通信提供服务
运输层端口号、复用和分用的概念
-
运行在计算机上的进程使用进程标识符PID来表示
-
因特网上的计算机并不是使用统一的操作系统,不同的操作系统(Windows,Linux,Mac OS)又使用不同的进程标识符
-
为了使运行不同操作系统的计算机的应用进程之间能够进行网络通信,就必须使用统一的方法对TCP/IP体系的应用进程进行标识
-
TCP/IP体系的运输层使用端口号来区别应用层的不同应用进程
- 端口号使用16bit标识取值为0 - 65535
- 熟知端口号: 0 - 1023 IANA把这些端口号指派给了TCP/IP体系中的最重要的一些应用协议: FTP(21/20),HTTP(80),DNS(53)
- 登记端口号:1024-49151 为没有熟知端口号的应用程序使用。使用这些端口号必须在IANA按照规定的手续登记,防止重复
- 短暂端口号:49152-65535 留给客户进程选择暂时使用,当服务器进程收到客户进程的报文时,就知道了客户进程所使用的动态端口号,通信结束后这个端口号可供其他客户进程以后使用
- 端口号使用16bit标识取值为0 - 65535
-
端口号只具有本地意义,知识为了表示本计算机应用层中的各进程,在因特网中,不同计算机中的相同端口号是没有联系的
-
复用
- UDP复用: 发送方某些应用进程发送的不同应用报文在运输层使用UDP协议进行封装
- TCP复用: 发送方某些应用进程发送的不同应用报文在运输层使用TCP协议进行封装
- IP复用 : UDP用户数据报或者TCP报文在网络层通过IP协议进行封装
-
分用
- IP分用 :将IP数据报的数据载荷部分所封装的UDP用户数据报或者TCP报文交付给运输层中的UDP或TCP
- UDP分用 和 TCP分用 : 将数据跟据端口号交付给不同的应用进程
TCP和UDP的区别
TCP的流量控制
所谓流量控制就是让发送方的发送速率不要太快,要让接收方来的及接受
利用滑动窗口机制可以很方便地在TCP连接上实现发送方的流量控制
TCP规定即使接收窗口为0也必须接受零窗口探测报文
TCP的拥塞控制
在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就要板坏,这种情况就叫做拥塞
- 在计算机网络中的链路容量,交换结点中的缓存和处理机等,都是网络的资源
若出现拥塞而不进行控制,整个网络的吞吐量将随输入负荷的增大而下降
四种拥塞控制算法
- 慢开始:慢启动,发送方每收到一个ACK,拥塞窗口cwnd的大小就会加1
- 拥塞避免算法 : 每个传输轮次结束后,拥塞窗口大小指数规律增长
出现报文丢失后,判断发生网络拥塞
-
快重传: 有时个别报文段会在网络上丢失,实际上网络并没有拥塞
- 这会导致发送方超时重传,并误认为网络发生了拥塞
- 发送方把拥塞窗口cwnd又设置为最小值1,并错误的启动慢开始算法,因此降低了传输效率
- 使用快重传算法可以让发送方尽早知道发生了个别报文段的丢失
- 快重传是指发送发尽快进行重传,而不是等超时重传计时器超时再重传
- 要求接收方不要等待自己发送数据时才进行捎带确认,而是立即发送确认
- 即使收到失序的报文段也要立刻发出对已收到的报文段的重复确认
- 发送方一旦收到3个连续的重复确认,就将相应的报文段立刻重传,而不是等该报文段的超时重传计时器超时在重传
快恢复
超时重传时机的选择
两个概念 往返时间 RTT0 超时重传时间RTO
当RTO小于RTT0时会出现不必要的重传,造成网络负荷增大
当RTO远大于于RTT0时会使网络的空闲时间增大,降低传输效率
超时重传时间RTO应略大于往返时间RTT,但在复杂的因特网中RTT是不确定的
可以看出RTO和RTT关系紧密,如果RTT错误,那么RTO也会是错误的
RTT的测量
TCP可靠传输的实现
- 以字节为单位的滑动窗口来实现可靠传输
TCP建立连接和断开连接
直接上图
三次握手
为什么是三次握手?
- 三次握手的首要原因就是不会建立历史连接
想象一个场景客户端向服务端发送一个SYN,但是被网络阻塞住了,然后客户端又发送了一个新的SYN,这时旧的SYN比新的SYN先到达了服务端,服务端收到后回复ACK/SYN给客户端,但是这时发的ACK的确认号与客户端期望的确认号是不一样的,客户端会发送一个RST去终止连接。这就是三次握手解决历史连接的方式。用图表示就是
为什么不是二次握手?
如果是二次握手的话那么SYN发过来的话,服务端就会进入到ESTABLISHEN状态,虽然客户端收到回复确认是历史连接了,因为服务端已经进入了ESTABLISHEN状态是能进行资源的发送的,也就是已经建立了历史连接了
- 第二个原因是同步双方初始序列号
TCP通信双方是要维护一个序列号的,有了序列号的好处就是- 避免重复数据
- 接收方可以实现按序接受
- 可以标识发送出去的数据包中, 哪些是已经被对方收到的(通过 ACK 报文中的序列号知道)
因此去建立连接的时候通信双方也需要将各自的初始序列号进行发送(SYN中携带),当客户端向服务端发送SYN时需要服务端回复ACK来应答,而服务端也需要发送SYN来告知初始序列号,客户端也需要发送ACK进行应答。
为什么不是四次握手?
服务端收到SYN进行应答时的ACK发送和发送自己的初始序列号SYN是可以一起发出的。
- 最后一个原因就是减少资源浪费
如果是两次握手的话,客户端发送一个SYN因为网络阻塞住了,客户端没有收到服务端的ACK,会重新去发送SYN,而二次握手服务端没收到一个SYN就会主动建立一个链接,这是很大的资源浪费。
四次挥手
四次挥手的状态变化
- 客户端主动断开向服务端发送一个FIN数据包,进入
FIN_WAIT1
状态 - 服务端收到后回复一个ACK,并进入
CLOSED_WAIT
状态,并传输未发送完的数据传输完之后 - 客户端收到回复后进入
FIN_WAIT2
状态 - 服务端 发送FIN数据包并进入
LAST_WAIT
状态 - 客户端收到FIN数据包后回复ACK进入
TIME_WAIT
状态,服务端收到ACK后进入CLOSED
状态,客户端在等待2MSL之后也进入CLOSED
状态
断开连接与建立连接为什么会差一次
建立连接时确认回复ACK和发送SYN是可以同时进行的,但是断开连接时第一次回复ACK和客户端发送FIN是不能同时进行,因为虽然服务端确定客户端要断开连接了,但是不代表服务端没有数据需要发送了。
为什么是2msl
msl 是 Maximum Segment Lifetime,报文最大生存时间
因为客户端发送ACK,服务端可能收不到,他会重发FIN给客户端,然后客户端重发ACK,2msl则是保证产生的报文会在网络中消失
注 : 2MSL 的时间是从客户端接收到 FIN 后发送 ACK 开始计时的。如果在 TIME-WAIT 时间内,因为客户端的 ACK 没有传输到服务端,客户端又接收到了服务端重发的 FIN 报文,那么 2MSL 时间将重新计时。
TCP报文段的首部格式
源端口:16bit ,写入端口号,用来标识发送该TCP报文段的应用进程
目的端口 : 16bit,写入目的端口号,用来标识接收该TCP报文段的应用进程
序号:32bit 取值范围[0,2^32-1]序号增加到最后一个后,下一个序号就又回到了0,指出本TCP报文段数据载荷的第一个字节的序号
确认号:32bit 取值范围[0,2^32-1]序号增加到最后一个后,下一个序号就又回到了0,指出期望收到对方下一个TCP报文段的数据载荷的第一个字节的序号,同时也是对之前收到的所有数据的确认
确认标志位ACK:取值为1是确认号字段有效,为0无效
数据偏移:4bit,并以4字节为单位,用来指出TCP报文段的数据载荷部分的起始处距离TCP报文段的起始处有多远
实际上指出了TCP报文段的首部长度
固定长度为 20字节,数据偏移字段的最小值为(0101)
最大长度为 60字节,数据偏移字段的最大值为(1111)
保留字段:6bit ,保留为今后使用,但目前应设置为0
窗口字段 : 16bit,以字节为单位,指出发送本报文段的一方的接收窗口
校验和:16bit ,检查范围包括TCP报文段的首部和数据载荷两部分。在计算校验和时,要在TCP报文段的前面加上12字节的伪首部
同步标志位SYN:在TCP连接建立时用来同步序号
终止标志位FIN:用来释放TCP连接
复位标志位RST:用来复位TCP连接,当RST=1时,表明TCP连接出现了异常,必须释放连接,然后重新建立连接,RST置1还用来拒绝一个非法的报文段或拒绝打开一个TCP连接
推送标志位PSH:接收方的TCP收到该表示为1的报文段会尽快上交应用进行,而不必等到接收缓存都填满后再向上交付
紧急标志位URG:取值为1时紧急指针字段有效;取值为0时紧急指针字段无效。
紧急指针:占16比特,以字节为单位,用来指明紧急数据的长度。
填充:由于选项的长度可变,因此使用填充来确保报文段首部能被4整除
(因为数据偏移字段,也就是首部长度字段,是以4字节为单位的)。