1. 简介
TCP 是一个面向连接的(connection-oriented)、可靠的(reliable)、基于字节流(byte-stream)、全双工(full-duplex)的协议。
1.1 面向连接
在发送数据之前,先通过三次握手建立一个逻辑连接,握手期间协商通信过程中的起始序列号,窗口大小等信息;
在发送数据之后,再通过四次挥手断开这个逻辑连接
1.2 可靠性
IP协议将收到的数据帧尽最大可能的发送到目的地址,不具备可靠性;它不保证发送的数据帧是否重复,也不保证接收方收到的数据帧顺序和发送的顺序一致,还不保证数据帧一定可以到达接收方;
TCP协议是建立在IP协议的基础上的,想要保证数据包的可靠性,就必须自己建立一套机制来保证数据包的可靠性,以下就是TCP保证数据包可靠性的一些机制;
1.2.1 校验和
TCP首部有2个字节表示校验和,通过校验和可以判断这个数据包的完整性,防止在发送过程中数据包的信息被篡改;
1.2.2 序列号
有些情况下可能会收到重复或者乱序的数据包,接收方可以根据数据包的序列号来判断这个数据包是否重复,并根据序列号重新排序数据包发送给上层应用;
1.2.3 超时重传
每发送一个数据包,就会启动一个定时器;如果在规定的时间没有收到该数据包的确认信息,则会重传间隔时间后重新发送该数据包,重传之后如果还没有收到确认信息,则在重传间隔时间后继续重传;
重传间隔时间会随重传次数的增加而进行指数级别的增加;
重传的最大次数有系统配置决定:/proc/sys/net/ipv4/tcp_retries2(默认值为15)
除了这种策略外,还有快速重传和SACK机制,可以根据使用场景灵活运用;
1.2.4 流量控制
流量控制可以通过滑动窗口进行协商调节;
发送方和接收方的数据处理能力可能有所不同,发送方要根据接收方的数据处理能力来发送数据。如果接收方下次只能处理200字节的数据,则发送方这次不能发送超过200字节的数据;
1.2.5 拥塞控制
数据从发送方到接收方,要经过物理链路的传输,在传输过程中,各个链路段的传输能力可能有所差别,TCP要根据数据传输的实时情况动态调整数据包的发送频率;
就像一个客运中心,如果路上的车比较多,比较堵,就降低发车的频率,如果路上比较通畅,则可以提高发车的频率;
1.3 基于字节流
TCP基于字节流,则表示TCP报文没有固定的边界;
在代码中我们可能一次写200字节,然后往内核刷一次数据,也可能一次写1000字节的数据,然后往内核刷一次数据;在这里面,我们往内核刷一次数据并不代表TCP就把这么多的数据写到一个TCP数据包发送出去了。
你可能一次往内核写入了2000个字节的数据,实际上TCP可能会把这2000个字节的数据分多个TCP数据包发送出去,可能第一次发送100个字节,第二次可能500个字节;
TCP一个数据包里面携带的数据多少是取决于诸多因素:路径最大传输单元 MTU、发送窗口大小、拥塞窗口大小等。
1.4 全双工协议
在 TCP 中发送端和接收端可以是客户端/服务端,也可以是服务器/客户端,通信的双方在任意时刻既可以是接收数据也可以是发送数据,每个方向的数据流都独立管理的序列号、滑动窗口大小、MSS 等信息。