12/5/2016 6:03:58 PM
概述
TCP和UDP同在一层–>运输层, 但是他们有很多不同.
TCP协议的特点
- TCP 提供可靠的 数据传输服务, TCP是面向连接的. 应用程序在使用TCP协议通信之前, 需要先建立连接
- TCP 连接是点对点的, 一条TCP连接只能连接两个端点
- TCP 提供可靠运输,无差错, 不重复, 按顺序.
- TCP 提供双全公通信, 允许通信双方任何时候都能发送数据, 因为TCP 连接的两端都设有发送缓存和接受缓存.
- TCP 面向 字节流. TCP 并不知道所传输的数据的含义, 仅把数据看作一连串的字节序列, 它不保证 接收方 收到的数据块和 发送方 发出的数据块具有大小对应关系
TCP 报文段结构
TCP是面向字节流的, 而TCP的传输数据的单元是报文段,一个TCP 报文段可分为两部分:
报头
和数据部分
.数据部分是上层应用交付的数据,而报头则是TCP功能的关键.
TCP 报文段
的报头
有 前 20字节的固定部分, 后面 4n 字节是根据需要而添加的字段, 如图是 TCP 报文段结构:
20字节的固定部分, 各字段功能说明:
- 1.源端口和目的端口:各占 2 个字节, 分别写入 源端口号 和目的端口号. 这和 UDP 报头有类似之处, 因为都是 运输层 协议
- 2.序号: 占 4 个字节, 序号范围:[0, 2^32 - 1], 序号增加到
2^32-1
后, 下个序号又回到 0 . TCP 是面向字节流的, 通过TCP传送的字节流中的每个字节都按顺序编号, 而报头中的序号字段值则指的是本报文段数据的 第一个字节的序号. - 3.确认号: 占 4 个字节, 期望收到对方下个报文段的第一个数据字节的序号.
- 4.数据偏移: 占 4 个字节, 指TCP报文段的报头长度, 包括固定的 20 字节 和选项字段.
- 5.保留: 6 个字节, 保留为今后使用, 目前为 0.
- 6.控制位:共有 6 个控制位, 说明本报文段的性质, 意义如下:
-
- URG紧急: 当 URG = 1 时, 它告诉系统此报文中有紧急数据, 应优先传输(比如紧急关闭), 这与
紧急指针
字段配合使用 - ACK确认: 仅当 ACk = 1时,
确认号
字段才有效. 建立TCP连接后, 所有报文段都必须把 ACK 置为 1 - PSH推送: 若TCP连接的一端希望另一端立即响应, PSH 字段便可以”催促”对方, 不再等到缓存区填满才发送.
- RET;复位: 若TCP连接出现严重差错, RST置为 1, 断开 TCP, 再重新建立连接
- SYN同步: 用于建立和释放连接, 稍后详细介绍.
- FIN终止: 用于释放连接, 当 FIN = 1, 表明发送方已经发送完毕, 要求释放TCP连接
- URG紧急: 当 URG = 1 时, 它告诉系统此报文中有紧急数据, 应优先传输(比如紧急关闭), 这与
- 7.窗口: 占 2 个字节. 窗口值是指发送者自己的接收窗口大小, 因为接受缓存的空间有限.
窗口字段明确指出了, 现在允许对方发送的数据量. 窗口值是经常动态变化的 - 8.检验和: 占 2 个字节, 和
UDP数据报
一样, 有一个检验和, 用于检验 报文是否存在传输过程中的差错 - 9.紧急指针: 占 2 个字节, 当 URG=1 时有效, 指出本报文段紧急数据的字节数.
- 10.选项: 长度可变, 最长可达 40 字节. 具体的选项字段, 需要时再做介绍
TCP连接的建立与释放
建立连接 (三次握手)
详解
- 1.客户端 发出 请求连接报文段–>其中报头控制位
SYN=1
, 初始序号
seq=x1
, 客户端进入 SYN-SENT(同步已发送)状态
- 2.服务器端 收到 请求报文段后, 向客户端发送确认报文段
–>确认报文段
的首部 SYN=1
, ACK=1
, 确认号是ack=x+1
, 同时为自己选择一个初始序号 seq=y
. 服务端进入 SYN-RCVD(同步收到)状态
.
- 3.客户端收到服务器端的 确认数据报段后, 还要给服务器端 发送一个 确认报文段, 这个 报文段中 ACK=1
,确认号 ack=y+1
, 而自己的序号 seq=x+1
. 这个报文段已经可以携带数据, 如果不携带数据则不消耗序号, 则下一个报文段序号仍为 seq=x+1 .
至此TCP连接已经建立, 客户端进入 ESTABLITSHED(已建立连接)
状态, 当服务器端收到确认后, 也进入ESTABLISHED状态
, 它们之间便可以正式传输数据了.
TCP释放连接 (四次挥手)
释放连接的详细过程:
- 1. 此时 TCP 连接的两端都还处于 ESTABLISHED 状态, 客户端停止发送数据, 并发出一个 FIN报文段
.首部FIN=1
, 序号seq=u
(u等于客户端传输数据最后一个字节的序号 加 1). 客户端进入 FIN-WAIT-1
(终止等待 1 )状态
- 2. 服务器端回复确认报文段, 确认号 ack=u+1
, 序号 seq=v
(v 等于 服务器端传输数据最后一个字节的序号 加 1), 服务端进入 CLOSE-WAIT(关闭等待)状态
. 现在TCP连接处于 半开半闭状态
, 服务器端如果继续发送数据, 客户端依然接收
- 3.客户端收到确认报文, 进入 FIN-WAIT-2状态
, 服务器端发送完数据后, 发出 FIN 报文段, FIN=1
, 确认号 ack=u+1, 然后进入LAST-ACK(最后确认)状态
- 4. 客户端回复确认报文段, ACK=1
, 确认号 ack=w+1
(w 为半开半闭状态时, 收到的最后一个字节数据的编码), 序号 seq=u+1
. 客户端进入到 TIME-WAIT
(时间等待)状态
注意此时连接还没有释放, 还需要时间等待 结束后 (4分钟) 两端才会CLOSED. 设置时间等待是因为, 有可能最后一个确认报文 地税而需要重传.
TCP 可靠传输的实现
- TCP 报文段的长度可变, 根据手法双方的缓存状态, 网络状态而调整,
- 当 TCP 收到 发自 TCP连接 另一端的数据, 它将发送一个确认.
- 当TCP发出一个段后, 它将启动一个定时器, 等待目的端确认收到这个报文段, 如果不能及时收到一个确认, 它将重发这个报文段, 这就是后面的 超时重发
- TCP 将保持 它的
首部
和 数据的检验和
. 如果通过检验和发现报文段有差错, 这个报文段将被丢弃, 等待 超时重传. - TCP 将数据按字节排序, 报文段 中有序号, 以确保顺序的正确性.
- TCP 还能提供流量控制. TCP 连接的话每一方都有手法缓存. TCP 的接收端只允许另一端发送接收端缓存所能接纳的数据. 这将防止较快的主机 致使 较慢的主机 缓存溢出.
可见超时重传机制 是 TCP 可靠性的关键, 只要没有得到确认报文段, 就重新发送数据, 直到收到对方的确认为止
超时重传
TCP规定, 接收者收到数据报后, 需要回复一个确认报文段, 以告知发送者数据已收到. 而发送者如果一段时间内(超时重传)没有收到确认报文段, 便重复发送:
为了实现超时重传, 需注意:
- 1.发送者发送一个报文段后, 暂时保存该报文段的副本, 为发生超时重传时使用, 收到确认报文段后删除该报文段
- 2.确认报文段也需要序号,才能明确是发出的哪个数据报得到了确认.
- 3.超时计时器比传输往返时间略长, 但具体值不确定的, 根据网络情况而变.
连续的ARQ协议
在实际应用中,并不是发送一个数据报都要等待确认.真实情况是, 采用流水线传输:发送方可以连续发送多个报文段(连续发送的数据长度叫做 窗口
), 而不必每发完一段就停止下来等待确认
实际应用中, 接收方也不必 对 收到每个报文的都做回复,
而是采用累积确认
方式: 接收者收到多个连续的报文段后, 只回复确认最后一个报文段, 表示在这之前的数据都已收到.
这样, 传输效率得到了很大提升.
流量控制和拥塞控制
由于接收方缓存的限制, 发送窗口 不能大于 接收方接收方窗口. 报文段首部有一个字段 叫做 窗口(rwnd)
, 这便是用于告诉对方自己的接受窗口–>可见接收窗口的大小是可以变化的
那么窗口的大小是如何变化的呢? TCP 对于拥塞的控制总结为 “慢启动, 加性增,乘性减” . 如图:
- 1.慢启动 :初始的窗口值很小,但是按指数规律渐渐增长,直到达到
慢开始门限(ssthresh)
。 2.加性增 :窗口值达到慢开始门限后,每发送一个报文段,窗口值增加一个单位量。
3.乘性减 :无论什么阶段,只要出现超时,则把窗口值减小一半。