TCP概述
RFC文档地址 TCP协议是TCP/IP协议簇中位于运输层的协议 可以看到运输层的两个主要协议除了TCP (
T
r
a
n
s
m
i
s
s
i
o
n
?
C
o
n
t
r
o
l
?
P
r
o
t
o
c
o
l
Transmission\ Control\ Protocol
Transmission?Control?Protocol,传输控制协议)还有一个UDP (
U
s
e
r
D
a
t
a
g
r
a
m
P
r
o
t
o
c
o
l
User Datagram Protocol
UserDatagramProtocol,用户数据报协议)
TCP和UDP有什么区别
- 连接:TCP提供面向连接的,可靠的的数据传输服务;而UDP提供的是无连接的,尽最大努力的数据传输服务,不保证传输的可靠性
- 服务对象:TCP是一对一的两点服务,即一条连接只有两个端点;UDP支持一对一,一对多,多对多的交互通信
- 可靠性:TCp是可靠交付数据的,数据可以无差错,不丢失,不重复,按需到达;UDP是尽最大努力交付,不保证可靠地交付数据
- 拥塞控制:TCP具有拥塞控制和流量控制的机制,保证了数据传输的安全性跟可靠性;UDP则没有相关的机制,即使网络非常拥塞也不影响其发送速率
- 首部开销:TCP首部长度较长,在没有使用“选项”字段时就已经需要20个字节;UDP首部只有8个字节,并且是固定不变的
- 传输方式:TCP是面向字节流的,是流式传输,没有边界,但保证顺序和可靠,其数据传输单位是报文段;UDP是一个包一个包地发送,是有边界的,但可能会丢包和乱序,传输单位为用户数据报
各自的应用场景:
- TCP:由于TCP是面向连接的,能保证数据的可靠性交付,经常用于:用于万维网的HTTP,HTTPS;用于文件传送的FTP;用于电子邮件传送的SMTP(简单邮件传送协议);用于远程终端接入的TELNET(远程终端协议)
- UDP不需要连接,可以随时发送数据,而且没有拥塞控制,经常用于:包总量较少的通信,如域名转换DNS,网络管理SNMP(简单网络管理协议);实时应用,如IP电话,实时视频会议等场景
可以看出衡量的点可以考虑所传数据的多少,对实时性要求的大小,对数据可靠性要求的大小 有的应用场景也并不是说只会使用两种其中一种协议,如DNS,一般使用UDP就足够,但也可能会出现需要访问较远距离的域名服务器的情况,此时就可能需要使用TCP了
TCP的服务模型
TCP提供了一种面向连接的,可靠的字节流服务 面向连接,即使用TCP的两个应用程序必须在双方交换数据之前必须建立一个TCP连接 在字节流抽象概念中,没有由TCP自动插入的记录标志或消息边界。连接的双方对数据进行读写时,读或写的次数以及每次读或写的大小由端点自己选择。TCP不会解读字节流里的字节内容,他不知道正在交换的数据字节是不是二进制数据,ASCII字符或其他东西。对字节流的解读只取决于连接的端点的应用程序
TCP的可靠性
TCP通过校验和,序列号,确认应答,连接管理,超时重传,滑动窗口机制,流量控制,拥塞控制等机制实现可靠性传输的
- 因为TCP提供的是字节流接口,它必须把一个发送应用程序的字节流转换成IP可以携带的分组,这被称为组包,这些分组就包含序列号,该序列号代表的是每个分组的第一个字节在整个数据流的字节偏移,这就允许了分组在传送中是可变大小的,并允许重新组包。由TCP传给IP的块称为报文段
s
e
g
m
e
n
t
segment
segment
- 如果一个携带无效校验和的报文段到达,那么TCP会丢弃它,不为被丢弃的分组发送任何确认
- TCP发送一组报文段时,会设置重传计时器,然后等待对方发送成功接收报文段的确认ACK,如果有ACK没有及时接收到,对应的报文段就会被重传。当TCP接收到连接的另一端的数据时,就会发送一个ACK。不过TCP使用的是累积确认,一个指示字节号N的ACK,暗示着所有直到N的字节都已经成功被接收了,这对于ACK丢失来说带来了一定的鲁棒性,如果一个ACK丢失,很有可能后续的ACK就足以确认前面的报文段了
- TCP提供的是全双工通信,数据可向两个方向流动,两个方向相互独立。每个方向上的报文段发送各自的ACK,同时包含窗口通告以实现相反方向上的流量控制
- 使用序列号,一个TCP接收端可丢弃重复的报文段和记录以杂乱次序到达的报文段。因为TCP使用IP来传递其报文段,IP不提供重复数据消除以及保证次序正确的功能。而TCP是一个字节流协议,绝不会以杂乱的次序给接收端应用程序发送数据,因此接收端会被迫先保持大序列号的数据不交给应用程序,直到中间缺失的部分小序列号的报文段接收到了,填补了整个字节流的空缺,再继续发送字节流
TCP的头部和封装
TCP在IP数据报中的封装如图: TCP头部如图:
- 每个TCP头部中都包含了源端口和目的端口,这两个值和IP头部中的源IP地址以及目的IP地址,这样的四元组唯一地表示了每个连接。一个IP地址和一个端口的组合有时又称为一个端点
e
n
d
p
o
i
n
t
endpoint
endpoint或套接字
s
o
c
k
e
t
socket
socket
- 序列号是一个32位的无符号数,每一个报文段对应一个序列号,它代表的就是该报文段的数据中第一个字节的序列号,因为TCP会给两个应用程序间通信的数据流中的每个字节都赋予一个序列号 (这里考虑的数据流只考虑一个方向上的,一个连接的两个方向相互独立)。序列号到达232 - 1后再循环到0
- 确认号 ACK包含的值是该确认号的发送方期待接收的下一个序列号,也即最后被成功接受的数据字节的序列号加1,也可以这么理解,对于发送这个ACK的通信方来说,这个序列号以前(不包括这个序列号)的所有序列号它都已经接收到了。这个字段只有在ACK位字段被启用的时候有效,而这个ACK位字段通常在一个连接中,除了初始报文段跟末尾报文段之外。其它报文段中都会启用。由于ACK就是报文段头部的一部分,所以发送一个ACK跟发送任何报文的开销是一样的
- 头部长度字段给出了头部的长度。因为头部中除了基本部分固定是20字节以外,选择字段的长度是可变的,所以这个头部长度字段是必需的。头部长度字段共占4位,它的值以32位为单位,也就是说,0000表示头部长度为0位,0001表示头部长度为32位,0010表示头部长度为64位…所以最大值1111表示长度为60字节,即TCP头部最长只能为60字节。而基本TCP头部长20字节,也就是说选项字段最长为40字节。也是因为头部长度字段以32位为单位,所以TCP头部的长度应该是32bit的倍数
- 保留字段保留为今后使用,目前全置0
- 头部中定义了8位控制位:
– CWR:拥塞窗口减 (发送方降低其发送速率) – ECE:ECN回显 (发送方接收到了一个更早的拥塞通告) – URG:紧急 (紧急指针字段有效,很少被使用) – ACK:确认 (确认号字段有效,建立连接之后一般都是启用状态) – PSH:推送 (接收方应尽快给应用程序传送这个数据,不过这个功能没被可靠地实现或用到) – RST:重置连接 (连接取消,经常是因为错误) – SYN:用于初始化一个连接的同步序列号 – FIN:该报文段的发送方已经结束向对方发送数据 - TCP的流量控制由每个端点使用窗口大小字段来通告一个窗口大小来完成。这个窗口大小是字节数,从接收方想要接收的那个字节开始算起。由于字段所占长度只有16位,所以窗口大小最大只能为65535字节,从而限制了TCP的吞吐量性能。不过有一个窗口缩放选项可允许对这个值进行缩放,给高速和大延迟网络提供了更大的窗口和改造性能
- 校验和字段由发送方进行计算和保存,然后由接收方验证
- 紧急指针字段只有URG位启用时才有效。其值是一个正偏移量,与报文段的序列号字段相加后得到的就是紧急数据的最后一个字节的序列号
- 选项字段:
> 最常见的选项是最大段大小MSS
M
a
x
i
m
u
m
?
S
e
g
m
e
n
t
?
S
i
z
e
Maximum\ Segment\ Size
Maximum?Segment?Size。连接的每个端点一般在它发送的第一个报文段,即SYN报文段上指定这个选项,MSS指定该选项的发送者在相反方向上希望接收到的报文段的最大值 > 除此之外还有SACK,时间戳和窗口缩放等选项
TCP其它部分
TCP的连接管理
|