https://cloud.tencent.com/developer/article/1900017
https://www.cnblogs.com/wuhongbin/p/15524638.html
TCP报文格式
TCP协议特点
- 点对点,面向连接
- 全双工 双向传递
- 字节流传输:打包成报文段、保证有序接收、重复报文被自动丢失
- 流量缓冲:解决速度不匹配的问题
- 可靠的传输服务(保证可达、丢包时通过重发时延实现可靠性)
- 拥塞控制
通过四元组实现面向连接(源地址、源端口、目标地址、目标端口)
TCP三次握手

大写的都是标志位,标志这个报文的类型 。小写seq是报文序列号,ack是确认序列号也是希望下一个报文的起始序列号。
syn洪泛攻击
攻击者通过发送大量的TCP SYN包,服务器返回ACK之后,不回应。
此时TCP连接处于挂起状态,服务器收不到客户端的ACK还会不断的发送ACK,占用服务器资源。
如果有大量被挂起的连接,服务器资源枯竭,导致正常连接无法握手。
为什么是三次?
为了保证可靠性,TCP的每一次消息都要确保正常收发。
三次才能验证双方的发送与接受的能力。
第一次握手成功后,服务端知道了客户端的发送能力。
第二次握手之后,客户端知道服务端能够正常接收到数据,也能正常发送。
第三次握手,服务端才能知道客户端能够正常接收数据。
如果没有了第三次,假设第二次握手的时候,服务端直接进入就绪状态。那么如果第二次握手失败,客户端还在等待回执,服务端却已经准备好,那么场面就陷入了尴尬。
如果第三次握手包丢失怎么样?
服务端处于SYN_REVD状态下,根据超时重传机制,重新发送确认报文,重传好几次还是没有成功,就关闭。
客户端此时在就绪状态,开始发送数据,但是服务端会返回RST包,客户端就知道有问题。释放连接,重新建立。
TCP四次挥手
为什么要四次挥手?
客户端发起关闭连接请求,服务端回复确认,仅代表客户端没有数据发送了。
但是,服务端还有数据没有发送完成,所以等 服务端数据发送完,服务端发起关闭连接请求,客户端确认后才确定可以关闭这次连接。
为什么在TIME-WAIT阶段必须等待2MSL时间?
MSL也就是报文生存的最大时间,超过这个时间的报文将丢弃。
如果客户端在发送最后一次握手的确认报文的时候就进入了closed状态。
如果最后一次报文丢失了,服务端要发起超时重传,但是重传的FIN报文永远不可能得到回应,服务端就不会释放。
总结
- TCP提供连接,让双方的传输更加稳定、安全
- TCP没有直接提供会话,因为应用对会话的需求多种多样,比如聊天程序会话在保持双方的聊天记录,电商程序会话在保持购物车、订单一致,所以会话通常在TCP连接上进一步封装,在应用层提供
- TCP是一个面向连接的协议,说的就是TCP协议参与的双方在收发数据之前会先建立连接。UDP是一个面向报文的协议—协议双方不需要建立连接,直接传送报文
- 连接需要消耗更多的资源
TCP粘包问题(了解)
拆包:数据被拆分成很多个部分,部分增加了协议头,合并成为一个TCP段,进行传输
本质来说TCP的粘包问题是因为它是基于字节流传输的,由于所有的数据都变成了01所以无法确定数据的边界,就可能导致前后数据粘连在一起。
网络像一根水管,也有通过性的要求,由数据链路层提供给网络层的MTU(最大传输单元)决定,一般为1500字节。那么由于MTU存在,所以向上的层级都需要将数据分包处理。网络层IP
数据链路层提供的MTU上层是网络层,那么先看IP协议是否会存在粘包问题。
IP协议中会根据MTU分为多个切片,每个切片中都有各自的 offset 和 IP地址,每个切片会可能通过不同的路由转发到接收端,接收端只需要根据IP和offset组装数据包就行。简单来说IP不需要管数据的边界,只要管数据从哪里到哪里。所以不存在粘包问题。传输层UDP
看完网络层,再看看传输层的UDP协议。
由于UDP是面向数据报传输的。UDP在接收到应用层的数据之后,不会进行数据包拆分和合并,每个数据包都保留边界,完整的丢给IP协议。所以也不存在粘包问题。UDP是一个无连接的,面向消息的传输层协议。UDP不会使用块的合并优化算法,发送方发送数据时,是一包一包的发送,不会把多个小包组合成大包一起发送。接受方收到的数据包都是以链式结构存储的,应用程序一次只能获取一个数据包,因此不会存在粘包问题。
TCP
TCP是一个基于字节流的传输服务,所谓流,就是说TCP所传输的数据是一连串数据,没有界限。发送方发送的若干个数据包到达接收方时,全部都放在接收缓冲区,后一包数据的头紧接着前一包数据的尾,应用程序无法区分数据包的头和尾。
为什么会出现粘包
TCP出现粘包的原因是多方面的,可能是来自发送方,也可能是来自接收方。
- 发送方原因
- TCP默认开启了Nagle算法(主要作用:减少网络中报文段的数量),而Nagle算法主要做两件事:
- 只有上一个分组得到确认,才会发送下一个分组;
- 收集多个小分组,在一个确认到来时一起发送。
Nagle算法导致发送方可能会把多个间隔较小、数据量小的数据包,合并成一个大的数据包,然后进行封包一次性发送出去,从而导致粘包问题。
- TCP默认开启了Nagle算法(主要作用:减少网络中报文段的数量),而Nagle算法主要做两件事:
接收方原因
目的
- TCP提供可靠的网络传输
- UDP提供报文交换能力基础上,尽可能地简化协议轻装上阵
- 可靠性
- TCP保证可靠性
- UDP只管发送报文
- 有无连接
- TCP有连接
- UDP无连接,只发送数据
- 流控技术
- TCP在发送缓冲区中存储数据,在接收缓冲区中接收数据
- UDP无相关技术
- 传输速度
- UDP传输速度快,因为协议简化,封包小,没有连接和可靠性检查
- 场景差异
- TCP不适合高速数据传输场景
