1、简介
- 一种面向连接的服务
- 传送数据单元是TCP报文段
- 由于提供可靠的、面向连接的服务,处理速度较慢,报文段首部占用了较多资源(20字节)
- 采用多路复用技术
- 采用全双工通信模式
- TCP连接以端到端的形式进行连接
- TCP的连接两端不是主机,也不是主机IP地址,更不是应用进程,而是连接的套接字(IP+端口)
- TCP连接::={}socket1,socket2}={(IP1,port1),(IP2,port2)}
2、TCP报文格式
1)首部结构
- 端口:源端口和目的端口占两个16尾(2个字节),端口是运输层与应用层的服务接口。运输层的复用和分用功能都要通过端口才能实现。
- 序号:占4个字节,在TCP连接中传输的数据流都会有一个序号,序号字段的值则指的是本报文段所发送的数据的第一个字节的序号。
- 确认号:占 4 字节,是期望收到对方的下一个报文段的数据的第一个字节的序号。
- 数据偏移:即首部长度,占4位,它指出 TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远。
- 紧急URG:当 URG = 1 时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。
- ACK:只有当 ACK = 1 时确认号字段才有效。当 ACK = 0 时,确认号无效。
- 推送 PSH:接收 TCP 收到 PSH = 1 的报文段,就尽快地交付接收应用进程,而不再等到整个缓存都填满了后再向上交付。
- 复位 RST :当 RST =1 时,表明 TCP 连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。
- 同步 SYN:同步 SYN = 1 表示这是一个连接请求或连接接受报文。
- 终止 FIN :用来释放一个连接。FIN =1 表明此报文段的发送端的数据已发送完毕,并要求释放运输连接。
- 窗口字段 :占 2 字节,用来让对方设置发送窗口的依据,单位为字节。
- 检验和:占 2 字节。检验和字段检验的范围包括首部和数据这两部分。在计算检验和时,要在 TCP 报文段的前面加上 12 字节的伪首部。
- 紧急指针: 占 16 位,指出在本报文段中紧急数据共有多少个字节(紧急数据放在本报文段数据的最前面)。
- 选项字段:长度可变。TCP 最初只规定了一种选项,即最大报文段长度 MSS。MSS 告诉对方 TCP:“我的缓存所能接收的报文段的数据字段的最大长度是 MSS 个字节。”
- 规定MSS的原因:若选择较小的 MSS 长度,网络的利用率就降低。若 TCP 报文段非常长,那么在 IP 层传输时就有可能要分解成多个短数据报片。在终点要把收到的各个短数据报片装配成原来的 TCP 报文段。当传输出错时还要进行重传。这些也都会使开销增大。
- 因此:MSS要尽可能的大,以节约传输资源
- 其他选项:包括窗口扩大选项(占3字节)、时间戳选项(占10字节)、选择确认选项等
- 填充:填充数据是为了使整个首部长度是 4 字节的整数倍。
2)数据包分析
- 源端口与目的端口:443,52765
- 传输序号:seq=36
- 确认号:ack=1
- TCP头部长度:20字节
- ACK=1:说明确认号字段有效,这是一个确认数据包
- 窗口大小:1124
- 校验和:0x6fde
3、TCP可靠传输的实现
1) 三次握手建立连接
- TCP 建立连接的过程叫做握手。
- 握手需要在客户和服务器之间交换三个 TCP 报文段。称之为三报文握手。
- 采用三报文握手主要是为了防止已失效的连接请求报文段突然又传送到了,因而产生错误。
- 第一次握手:客户发送SYN=1和选择序号seq=x,表明这是一个请求连接的报文,并且传送数据是的第一个数据字节的序号是x
- 第二次握手:服务端回复客户端,如同同意连接则回复确认信息,在确认报文中应使SYN=1,ACK=1,确认序号ack=x+1,自己选择的序号seq=y
- 第三次握手:客户端收到确认报文后,想服务端确认,使其确认报文ACK=1,确认号ack=y+1,序号seq=x+1,然后通知上层应用,连接已经建立
2)四次挥手关闭连接
- 数据传输结束后,通信的双方都可释放连接
- TCP 连接释放过程是四报文挥手。
- 第一次挥手:数据传输完成之后,通信双方都可以释放连接,一客户端限时房为例,客户端使连接释放报文段的FIN=1,序号seq=u,发送给服务端之后等待确认、
- 第二次挥手:服务端使回复本文中的ACK=1,ack=u+1,seq=v,并通知高层应用进程,此时练级处于办关闭状态,客户端到服务端的连接已经关闭,服务端若发送数据,客户端仍可以接收
- 第三次挥手:若服务端没有数据要发送,其应用进程就通知TCP释放连接,发送连接释放报文段,使ACK=1,seq=w,ack=u+1
- 第四次挥手:客户端收到连接释放报文后,回复确认信息,使ACK=1,seq=u+1,ack=W+1,至此连接彻底关闭
3)拥塞控制
- TCP 采用基于窗口的方法进行拥塞控制。
- TCP发送方维持一个拥塞窗口 CWND (Congestion Window)
- 拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化
- 发送端利用拥塞窗口根据网络的拥塞情况调整发送的数据量
控制拥塞窗口的原则:
- 只要网络没有出现拥塞,拥塞窗口就可以再增大一些,以便把更多的分组发送出去,这样就可以提高网络的利用率。
- 但只要网络出现拥塞或有可能出现拥塞,就必须把拥塞窗口减小一些,以减少注入到网络中的分组数,以便缓解网络出现的拥塞。
拥塞的判断:
-
重传定时器超时:现代通信的传输速度快,真常情况不会超时马若出现超时,则可以猜测出现了拥塞
-
收到三个相同的ACK:个别报文段会在网络中丢失,预示可能会出现拥塞(实际未发生拥塞),因此可以尽快采取控制措施,避免拥塞。
拥塞控制算法:
- 慢开始
- 拥塞避免
- 快重传
- 快恢复
慢开始算法:
- 算法的思路:由小到大逐渐增大拥塞窗口数值。
- 初始拥塞窗口值cwnd的设定:RFC 5681 把初始拥塞窗口 cwnd 设置为不超过2至4个SMSS 的数值。
- 慢开始门限 ssthresh(状态变量):防止拥塞窗口cwnd 增长过大引起网络拥塞。
- 拥塞窗口 cwnd 控制方法:在每收到一个对新的报文段的确认后,可以把拥塞窗口增加最多一个 SMSS 的数值。
- 发送方每收到一个对新报文段的确认重传的不算在内)就使 cwnd 加 1。
- 每经过一个传输轮次,拥塞窗口就加倍。实际窗口大小按指数增加,并不慢!
- 慢开始门限 ssthresh 的用法:当 cwnd < ssthresh 时,使用慢开始算法。当 cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法。
拥塞避免算法:
- 算法思路:让拥塞窗口 cwnd 缓慢地增大,即每经过一个往返时间 RTT 就把发送方的拥塞窗口 cwnd 加 1,而不是加倍,使拥塞窗口 cwnd 按线性规律缓慢增长。
- 当增加到一定大小时,出现拥塞(重传计时器超时),此时,使慢开始门限ssthresh = max(cwnd/2,2),窗口大小cwnd=1,再次执行慢开始算法
实例举例:
快重传算法:
- 采用快重传FR (Fast Retransmission) 算法可以让发送方尽早知道发生了个别报文段的丢失。
- 快重传 算法首先要求接收方不要等待自己发送数据时才进行捎带确认,而是要立即发送确认,即使收到了失序的报文段也要立即发出对已收到的报文段的重复确认。
- 发送方只要一连收到三个重复确认,就知道接收方确实没有收到报文段,因而应当立即进行重传(即“快重传”)
- 使用快重传可以使整个网络的吞吐量提高约20%。
快恢复算法:
当发送端收到连续三个重复的确认时,由于发送方现在认为网络很可能没有发生拥塞,因此现在不执行慢开始算法,而是执行快恢复算法 FR (Fast Recovery) 算法:
- 慢开始门限 ssthresh = 当前拥塞窗口 cwnd / 2 ;
- 新拥塞窗口 cwnd = 慢开始门限 ssthresh ;
- 开始执行拥塞避免算法,使拥塞窗口缓慢地线性增大。