概述
负责向两个主机中的进程之间的通信提供服务,还有一个重要的功能复用,分用
复用——在发送方所有进程都可以使用一个运输层协议
分用——接收方在剥去运输层首部后能将数据正确交付目的进程
UDP协议
UDP特点:无连接、尽最大努力交付、面向报文
报文格式:
首部字段只有 8 个字节,包括源端口、目的端口、长度、检验和。12 字节的伪首部是为了计算检验和临时添加的。
TCP协议
特点:面向连接、提供可靠服务、双全工通信、面向字节流
每一条TCP连接唯一的被通信两端的端点(即两个套接字)所确定
套接字socket=(IP地址:端口号)
首部格式
- 序号:对字节流编号
- 确认号:期望收到下一个报文段的序号
- 数据偏移:指数据部分距离报文段起始处的偏移量,实际上指首部长度
- 确认ACK:当ACK=1确认号有效,TCP规定,在建立连接后,所有传送的报文段都必须把报文段置为1
- 同步SYN:在连接建立时用来同步序号。当SYN=1,ACK=0表示这是一个连接请求报文段。若对方同意连接,则响应报文中SYN=1,ACK=1
- 终止FIN:用来释放一个连接
- 窗口:窗口值用来作为接收方让发送方设置其发送窗口的依据,因为接收方的数据缓存空间是有限的
三次握手
连接过程
B处于LISTEN(监听)状态,等待客户的连接请求
- A向B发送连接请求,SYN=1,ACK=0,选择一个初始序号seq=x
- B收到连接请求报文,如果同意,则向A发送连接确认报文,SYN=1,ACK=1,ack=x+1,同时选择一个初始序号y
- A收到B的连接确认报文后,还要向B发出确认,ACK=1,seq=x+1,ack=y+1
B收到A的确认后,连接建立
SYN=1的报文段不能携带数据,所以2、3中ack=x+1(y+1)
seq-序号
ack-确认号
三次握手原因
第三次握手时为了防止失效的连接请求到达服务器,让服务器错误打开连接
客户端发送的连接请求如果在网络中滞留,那么服务器会隔很长时间才会发回连接确认。而客户端等待一个超时重传时间之后,就会重新请求连接。但是这个滞留的请求连接最后还是会到达服务器,如果不进行三次握手,那么服务器就会打开两个连接。如果有三次握手,客户端就会忽略服务器对之后连接请求的连接确认,不进行第三次握手,因此就不会再次打开连接。
四次挥手
连接过程
- A发送连接释放报文,FIN=1
- B收到之后发出确认,此时TCP连接属于半关闭,B可以向A发送但A不能向B发送
- 当B不再需要连接时,发送连接确认报文,FIN=1
- A收到之后发出确认,进入time-wait状态,等待2MSL(最大报文存活时间)后释放连接
B收到A的确认之后释放连接
四次挥手原因
服务器端收到客户端FIN连接释放报文之后,进入CLOSE-WAIT状态而并不是马上关闭,原因是为了让服务器端发送还未传送完毕的数据
客户端收到服务器端FIN连接释放报文之后,进入TIME-WAIT状态而不是马上关闭,原因是:
- 确保最后一个确认报文能够到达。如果B没有收到A发来的确认报文,那么就会重新发送连接释放报文,A等待这一段时间就是为了防止这一情况发生
- 清除本持续时间内产生的所有报文,使下一个新的连接不会出现这种旧的连接报文
可靠传输
TCP 使用超时重传来实现可靠传输:如果一个已经发送的报文段在超时时间内没有收到确认,那么就重传这个报文段。
滑动窗口
TCP滑动窗口以字节为单位。
发送方收到确认,将窗口向前滑动至左部第一个没有确认
接收方对按序收到的数据中最高位序号给出确认,对未按序到达的数据暂时缓存
流量控制
流量控制即让发送方的发送速率不要太快,要让接收方来得及接收
接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据。
死锁:B向A发送零窗口报文段,过一段时间B有存储空间,又向A发送rwnd=400的报文字段,但是丢失,这时A等B发送非零窗口报文,B等A发送数据,陷入死锁
解决:TCP为每一个连接设置一个持续计时器,当A收到B发送的零窗口报文,计时器启动,到时后A发送一个零窗口探测报文
拥塞控制
如果网络出现拥塞,分组将会丢失,此时发送方会继续重传,从而导致网络拥塞程度更高。因此当出现拥塞时,应当控制发送方的速率。这一点和流量控制很像,但是出发点不同。流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度。
慢开始与拥塞避免
慢开始:从初始值开始,从小慢慢增大,每经过一个传输轮次,拥塞窗口cwnd就加倍
拥塞避免:给慢开始设置一个阀值,当到达阀值,每经过一个传输轮次拥塞窗口就+1
快重传与快恢复
快重传:在发送方,如果收到三个重复确认,那么可以知道下一个报文段丢失,此时执行快重传,立即重传下一个报文段。例如收到三个 M2,则 M3 丢失,立即重传 M3。
快恢复:在这种情况下,只是丢失个别报文段,而不是网络拥塞。因此执行快恢复,令 ssthresh = cwnd / 2 ,cwnd = ssthresh,注意到此时直接进入拥塞避免。(不直接降到零而是阀门值一半)