TCP是什么?
面向连接、保证可靠性传输、基于字节流的传输层通信协议
TCP协议解决的是什么问题?
保证端到端数据传输的可靠性
TCP如何保证可靠性?
- 应用数据被分割成 TCP 认为最适合发送的数据块。
- TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。
- 校验和: TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。
- TCP 的接收端会丢弃重复的数据。
- 流量控制: TCP 连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制)
- 拥塞控制: 当网络拥塞时,减少数据的发送。
- ARQ协议: 也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。
- 超时重传: 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。
连接管理
建立连接三次握手,客户端SYN、服务端SYN+ACK、客户端ACK。
断开连接四次握手,客户端FIN、服务端ACK、服务端FIN+ACK、客户端ACK。
校验和
IP报文头的校验和只校验IP首部,TCP报文头的校验和校验的是首部和数据。
tcp报文头部有校验和,发送方生成校验和,接收方检验校验和,传输过程检验到报文有差错直接丢弃。
报文编号
- 检测丢失:接收方可以知道少了哪些数据。
- 检测乱序:发送方的报文可能因为网络拥堵乱序到达接收方,接收方可以按照序号重新排序拼接报文,再转交完整的数据给应用层。
- 检测重复:接收方可以根据编号丢弃已经收到的报文,因为同一个编号的报文可能会因为超时重传机制多次发送。
确认应答
每次接收方收到数据后,会回应ACK确认应答报文给发送方,发送方就知道了这个包没有丢失,而是已经传输成功了。
超时重传
每个报文发送后都会开启一个定时器,超时前收到该编号报文确认应答的报文时则取消计时,如果不能及时收到确认则会重新发送这个报文。
超时重传有两种情况,一种是发送的报文未达到接收方,一种是接收方发送的ACK确认报文未达到发送方;前者的情况在接收方收到报文后会正常的发送ACK报文;后者的情况会丢弃编号重复的报文直接发送ACK确认报文。
流量控制
如果发送方发生数据过快,接收方来不及处理,接受方只能丢弃数据,这样浪费了流量,增加了不必要的消耗,接收方要告诉发送方自己能接受处理数据的最大数据量是多少,别多发不能处理的数据。
是通过ACK报文头中的窗口大小字段来告知对方自己还能接受多少数据,要发送数据的一方的发送窗口大小就是这个ACK报文头中的窗口大小与拥塞窗口大小的较小值
拥塞控制
流量控制是假设网络不拥堵,只考虑两端数据处理能力,但是整个网络如果发生拥堵,还需另外的处理,即拥塞控制。
拥塞控制主要是四个算法:慢启动、拥塞避免、快重传、快恢复
面向字节流是什么意思?
消息是「没有边界」的,所以无论我们消息有多大都可以进行传输。并且消息是「有序的」,「前一个」消息没有收到的时候,即使它先收到了后面的字节已经收到,那么也不能扔给应用层去处理,同时对「重复」的报文会自动丢弃。
TCP报文头格式是怎样的?
TCP报文头部最大为60字节,头部固定20个字节,TCP Options最大为40字节
包含源端口、目的端口、序列号、确认号、数据偏移、保留位、控制位、窗口大小、校验和、紧急指针、选项等
控制位:
CWR:用于 IP 首部的 ECN 字段。ECE 为 1 时,则通知对方已将拥塞窗口缩小。
ECE:在收到数据包的 IP 首部中 ECN 为 1 时将 TCP 首部中的 ECE 设置为 1,表示从对方到这边的网络有拥塞。
URG:紧急模式
ACK:确认
PSH:推送,接收方应尽快给应用程序传送这个数据。没用到
RST:该位为 1 表示 TCP 连接中出现异常必须强制断开连接。
SYN:初始化一个连接的同步序列号
FIN:该位为 1 表示今后不会有数据发送,希望断开连接。
为什么 TCP 协议有性能问题?
在弱网环境下(丢包率高)影响 TCP 性能的三个原因:
- TCP 的拥塞控制算法会在丢包时主动降低吞吐量;
- TCP 的三次握手增加了数据传输的延迟和额外开销;
- TCP 的累计应答机制导致了数据段的传输;
如何唯一的标识和确认一个TCP连接?
四元组。
源IP地址、源端口号、目的IP地址、目的端口号。
TCP最大连接数是多少?
服务端固定监听某个端口。
源IP地址在IP报文头中是32位。
源端口号在TCP报文头是16位。
不考虑其他因素,理论最大连接数是 2^32 * 2^16
。
为什么TCP报文头里没有数据长度,UDP报文头里有数据长度?
TCP数据长度 = IP总长度 - IP首部长度 - TCP首部长度
UDP数据长度 = IP总长度 - IP首部长度 - UDP首部长度
UDP数据长度是可以通过IP总长度减去报文头长度算出来了的。
UDP报文头里有数据长度,是为了网络设备硬件设计和处理方便,首部长度需要是4字节的整数倍。