TCP/IP 的运输层有两个主要协议:
两个对等运输实体在通信时传送的数据单位叫作运输协议数据单元 TPDU (Transport Protocol Data Unit)。
TCP 传送的数据单位协议是 TCP 报文段(segment)。
UDP 传送的数据单位协议是 UDP 用户数据报。
UDP
- 无连接
- 尽最大努力交付
- 面向报文
- 没有拥塞控制
- 支持单播、多播、广播
- 首部开销小
UDP的校验和是把首部和数据部分一起都检验。
TCP
- 面向连接的运输层协议
- 只能点对点通信
- 提供可靠交付的服务
- 提供全双工通信
- 面向字节流
TCP 连接的端点叫做套接字 (socket) 或插口;端口号拼接到 (contatenated with) IP 地址即构成了套接字。
同一个 IP 地址可以有多个不同的 TCP 连接;同一个端口号也可以出现在多个不同的 TCP 连接中。
停止等待协议(自动重传请求 ARQ (Automatic Repeat reQuest))
连续 ARQ 协议(滑动窗口协议、累积确认、Go-back-N(回退 N))
TCP可靠传输的实现
以字节为单位的滑动窗口
超时重传
选择确认的SACK
TCP 的流量控制
- 利用滑动窗口实现流量控制
TCP 的拥塞控制
TCP 采用基于窗口的方法进行拥塞控制。该方法属于闭环控制方法。
TCP发送方维持一个拥塞窗口 cwnd (Congestion Window)
发送端利用拥塞窗口根据网络的拥塞情况调整发送的数据量。
发送窗口大小不仅取决于接收方窗口,还取决于网络的拥塞状况,所以真正的发送窗口值为:
TCP拥塞控制算法
• 慢开始 (slow-start)• 拥塞避免 (congestion avoidance)• 快重传 (fast retransmit)• 快恢复 (fast recovery)
初始化时,将拥塞窗口置为 1。
慢开始门限的初始值设置为 16 个报文段,即 ssthresh = 16。
发送方每收到一个对新报文段的确认 ACK,就把拥塞窗口值加 1,然后开始下一轮的传输。因此拥塞窗口 cwnd 随着传输轮次按指数规律增长。
当拥塞窗口 cwnd = 24 时,网络出现了超时(图中的点2 ),发送方判断为网络拥塞。于是调整门限值 ssthresh = cwnd / 2 = 12,同时设置拥塞窗口 cwnd = 1,进入慢开始阶段。
按照慢开始算法,发送方每收到一个对新报文段的确认 ACK,就把拥塞窗口值加 1。当拥塞窗口 cwnd = ssthresh = 12 时(图中的点3,这是新的 ssthresh 值),改为执行拥塞避免算法,拥塞窗口按线性规律增大。
当拥塞窗口 cwnd = 16 时(图中的点4),出现了一个新的情况,就是发送方一连收到 3 个对同一个报文段的重复确认(图中记为 3-ACK)。发送方改为执行快重传和快恢复算法。
主动队列管理AQM
所谓“主动”就是不要等到路由器的队列长度已经达到最大值时才不得不丢弃后面到达的分组,而是在队列长度达到某个值得警惕的数值时(即当网络拥塞有了某些拥塞征兆时),就主动丢弃到达的分组。
TCP连接
1.连接建立
TCP 连接的建立采用客户服务器方式。
主动发起连接建立的应用进程叫做客户 (client)。
被动等待连接建立的应用进程叫做 服务器 (server) 。
TCP 建立连接的过程叫做 握手 。l 握手需要在客户和服务器之间交换三个 TCP 报文段。称之为 三报文握手 。l 采用 三报文握手 主要是为了 防止已失效的连接请求报文段突然又传送到了 ,因而产生错误。
- A主动打开连接,B被动打开连接
- B的TCP服务器进程创建传输控制块TCB,B处于LISTEN(收听)状态
- A的TCP客户进程创建传输控制块TCB,开始发送连接请求的报文段(首部同部位SYN=1,初始序号seq=x,表明传送数据时的第一个数据字节的序号是 x),A进入SYN-SENT(同步已发送)状态。
- B收到连接请求报文段后,如果同意建立连接,则向A发送确认(确认报文段中应使 SYN = 1,使 ACK = 1,其确认号 ack = x + 1,自己选择的序号 seq = y),B进入SYN-RCVD(同步收到)状态。
- A收到B的确认后,还要向B确认(确认报文段的ACK置1,确认号ack=y+1,自己的序号seq=x+1),A进入ESTABLISHED(已建立连接)状态。
- B收到A的确认后,也进入ESTABLISHED(已建立连接)状态。
---------------------
ACK是确认,当且仅当ACK=1时,确认号字段ack才有效
ack是确认号,期望收到对方下一个报文段的第一个数据字节的序号
seq是序号,本报文段所发送的数据的第一个字节的序号
为什么A最后还要发送一次确认呢?
为了防止已失效的连接请求报文段突然又传送到了B,因为产生错误。
扩展:四报文握手(B给A发送报文段拆成两次,一次(SYN=1,ack=x+1),第二次(SYN=1,seq=y))
2.连接释放
TCP 连接释放过程是四报文握手
- A和B处于ESTABLISHED状态
- A发出连接释放报文段,并停止再发送数据,主动关闭 TCP 连接(连接释放报文段首部的FIN = 1,其序号seq = u,等待 B 的确认),A进入FIN-WAIT-1(终止等待1)状态。[TCP规定,FIN报文段即使不携带数据也要消耗一个序号]
- B收到连接释放报文段后即发出确认(确认号ack=u+1,seq=v),B进入CLOSE-WAIT(关闭等待)状态。【A到B这个方向的连接就释放了,TCP连接处于半关闭(half-close)状态,即A没有数据要发给B了,但B若要发送数据给A,A任要接收】
- A收到B的确认之后,进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段。
若 B 已经没有要向 A 发送的数据,其应用进程就通知 TCP 释放连接(连接释放报文段FIN=1,seq=w,ack=u+1,ACK=1),B进入 LAST-ACK(最后确认)状态 。 A 收到连接释放报文段后,必须发出确认(在确认报文段中 ACK = 1 ,确认号 ack = w + 1 ,自己的序号 seq = u + 1),进入 TIME-WAIT(时间等待)状态 。[ TCP连接仍未释放 ] B接收到A的确认后,关闭连接,进入 CLOSED状态。 A再经过时间等待计时器(TIME-WAIT timer)设置的时间2MSL(最长报文段寿命,建议设为2分钟)后,A才进入到 CLOSED状态。为什么A在 TIME-WAIT(时间等待)状态 必须等待2MSL的时间呢?
- 保证最后一个ACK顺利送到,因为B如果长时间收不到这个ACK,B会超时重传FIN的,而这时A正好有时间接收到,重发一次ACK。
- 可以使本连接持续时间内所产生的所有报文段(包含“已失效的连接请求报文段”)都从网络中消失
除了时间等待计时器,还设有一个保活计时器:
- 用来防止在TCP连接出现长时期的空闲。
保活计时器通常设置为 2 小时 。若服务器过了 2 小时还没有收到客户的信息,它就发送探测报文段。若发送了 10 个探测报文段(每一个相隔 75 秒)还没有响应,就假定客户出了故障,因而就终止该连接。