TCP首部
源端口号和目标端口号:各占两个字节,分别写入源端口号和目标端口号。
序号:占4个字节,在建立连接时由计算机生成的随机数作为其初始值,通过 SYN 包传给接收端主机,每发送一次数据,就「累加」一次该「数据字节数」的大小。用来解决网络包乱序问题。
确认号:占4个字节,指下一次期望收到的数据的序号,发送端收到这个确认应答以后可以认为在这个序号之前的数据都以及被正常接收。用来解决不丢包的问题。
首部长度:占4个二进制位,表示TCP首部的总长度。一个数据表示4个字节,即1111表示60个字节,所以TCP首部长度最大为60个字节,选项部分最大为40个字节。
保留位:占6个二进制位,保留为以后使用。
接下来有6个控制位,均占一个二进制位:
URG(urgent):当URG = 1时,紧急指针字段生效。它告诉系统此报文段中有紧急数据,应尽快发送(相当于高优先级的数据),而不要按原来的排队顺序来传送。
ACK(acknowledgement):当ACK = 1时,确认号字段生效。TCP规定除了最初建立连接时的SYN包之外该位必须为1。
PSH(push):发送方将PSH位设置为1时,接收方接收到这个报文段就会尽快处理,不需要按照原来的顺序排队等待。
RST(reset):当RST = 1时,说明TCP会话出现异常,必须强制断开连接。要想正常通讯,要重新建立连接。
SYN(synchronization):在连接建立时用来同步序号。当SYN = 1而ACK = 0时,表明这是一个连接请求报文段。对方若同意建立连接,则应在响应的报文段中使SYN = 1和ACK = 1,因此SYN置为1就表示这是一个连接请求或连接接受报文。
FIN(finis):当FIN = 1时,表示今后不会在有数据发送,希望断开连接。
接收窗口:占2个字节。接收窗口指的是发送本报文段的一方的接收窗口。接收窗口值告诉对方:接收缓存现在能放多少字节,用于流量控制。
校验和:占2个字节。检验和字段检验的范围包括首部和数据这两部分。和UDP用户数据报一样,在计算检验和时,要在TCP报文段的前面加上12字节的伪首部。伪首部的格式和UDP用户数据报的伪首部一样。但应把伪首部第4个字段中的17改为6(TCP的协议号是6),把第5字段中的UDP中的长度改为TCP长度。接收方收到此报文段后,仍要加上这个伪首部来计算检验和。若使用IPv6,则相应的伪首部也要改变。
紧急指针:占2字节。紧急指针仅在URG = 1时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据) 。因此,在紧急指针中指出了紧急数据的末尾在报文段中的位置。当所有紧急数据都处理完时,TCP就告诉应用程序恢复到正常操作。值得注意的是,即使窗口为0时也可以发送紧急数据。
TCP基本认识
为什么需要 TCP 协议?TCP工作在那一层?
IP层是“不可靠”的,它不保证网络包的交付、不保证网络包的按序交付、也不保证网络包中的数据完整性。
如果需要保障网络数据包的可靠性,那么就需要由上层(运输层)的TCP协议来负责。
因为TCP是一个工作在运输层的可靠数据传输的服务,它能确保接收端接收的网络包是无损坏、无间隔、非冗余和按序的。
什么是TCP?
TCP是面向连接的、可靠的、基于字节流的传输层协议。
- 面向连接:一定是一对一才能连接,不能像UDP协议,可以一个主机同时向多个主机发送消息,也就是一对多是无法做到的。
- 可靠的:无论网络链路中出现了怎样的变化,TCP都可以保证一个报文一定能够到达接收端。
- 字节流:消息是没有边界的,所以无论我们消息有多大都可以进行传输。并且消息是有序的,当前一个消息没有收到的时候,即使后面的字节以及收到,那么也不能扔给应用层去处理,同时对重复的报文会自动丢弃。
什么是TCP连接?
用于保证可靠性和流量控制维护的某些状态信息,这些信息的组合,包括Socket、序号和窗口大小称为连接。所以我们知道,建立一个TCP连接是需要客户端和服务器端达成上述三个信息的共识。
- Socket:由IP地址和端口号组成
- 序号:用来解决网络包的乱序问题等。
- 窗口大小:用来做流量控制
如何唯一确定一个TCP连接?
TCP 四元组可以唯一的确定一个连接,四元组包括如下:
- 源地址
- 源端口
- 目的地址
- 目的端口
源地址和目的地址的字段(32位)是在 IP 头部中,作用是通过 IP 协议发送报文给对方主机。
源端口和目的端口的字段(16位)是在 TCP 头部中,作用是告诉 TCP 协议应该把报文发给哪个进程。
有一个 IP 的服务器监听了一个端口,它的 TCP 的最大连接数是多少?
服务器通常固定在某个本地端口上监听,等待客户端的连接请求。
因此,客户端 IP 和 端口是可变的,其理论值计算公式如下:
最大TCP连接数 = 客户端 IP 数 ✖ 客户端的端口数
对 IPv4,客户端的 IP 数最多为 2 的 32 次方,客户端的端口数最多为 2 的 16 次方,也就是服务端单机最大 TCP 连接数,约为 2 的 48 次方。
当然,服务端最大并发 TCP 连接数远不能达到理论上限。
- 首先主要是文件描述符限制,Socket 都是文件,所以首先要通过 ulimit 配置文件描述符的数目;
- 另一个是内存限制,每个 TCP 连接都要占用一定内存,操作系统是有限的。
UDP 和 TCP 有什么区别呢?分别的应用场景是?
UDP 不提供复杂的控制机制,利用 IP 提供面向「无连接」的通信服务。
UDP 协议非常简单,头部只有 8 个字节( 64 位),UDP 的头部格式如下:
- 目标和源端口:主要是告诉 UDP 协议应该把报文发给哪个进程。
- 包长度:该字段保存了 UDP 首部的长度跟数据的长度之和。
- 校验和:校验和是为了提供可靠的 UDP 首部和数据而设计。
TCP 和 UDP 区别:
1.连接
- TCP 是面向连接的运输层协议,传输数据前先要建立连接。
- UDP 是不需要连接,即刻传输数据。
2.服务对象
- TCP 是一对一的两点服务,即一条连接只有两个端点。
- UDP 支持一对一、一对多、多对多的交互通信
3.可靠性
- TCP 是可靠交付数据的,数据可以无差错、不丢失、不重复、按需到达。
- UDP 是尽最大努力交付,不保证可靠交付数据。
4.拥塞控制、流量控制
- TCP 有拥塞控制和流量控制机制,保证数据传输的安全性。
- UDP 则没有,即使网络非常拥堵了,也不会影响 UDP 的发送速率。
5.首部开销
- TCP 首部长度较长,会有一定的开销,首部在没有使用「选项」字段时是 20 个字节,如果使用了「选项」字段则会变长的。
- UDP 首部只有 8 个字节,并且是固定不变的,开销较小。
TCP 和 UDP 应用场景:
由于 TCP 是面向连接,能保证数据的可靠性交付,因此经常用于:
- FTP 文件传输
- HTTP / HTTPS
由于 UDP 面向无连接,它可以随时发送数据,再加上UDP本身的处理既简单又高效,因此经常用于:
- 包总量较少的通信,如 DNS 、SNMP 等
- 视频、音频等多媒体通信
- 广播通信
为什么 UDP 头部没有「首部长度」字段,而 TCP 头部有「首部长度」字段呢?
原因是 TCP 有可变长的「选项」字段,而 UDP 头部长度则是不会变化的,无需多一个字段去记录 UDP 的首部长度。
为什么 UDP 头部有「包长度」字段,而 TCP 头部则没有「包长度」字段呢?
TCP 计算负载数据长度:
TCP数据的长度 = IP总长度 - IP首部长度 - TCP首部长度
其中 IP 总长度 和 IP 首部长度,在 IP 首部格式是已知的。TCP 首部长度,则是在 TCP 首部格式已知的,所以就可以求得 TCP 数据的长度。
同样UDP的数据长度也可以通过这个公式得出,所以UDP包长度字段是冗余的。
为了网络设备硬件设计和处理方便,首部长度需要是 4字节的整数倍。如果去掉 UDP 「包长度」字段,那 UDP 首部长度就不是 4 字节的整数倍了,所以可能是为了补全 UDP 首部长度是 4 字节的整数倍,才补充了「包长度」字段。