https://cloud.tencent.com/developer/article/1900017
https://www.cnblogs.com/wuhongbin/p/15524638.html

TCP报文格式

image.png

TCP协议特点

  1. 点对点,面向连接
  2. 全双工 双向传递
  3. 字节流传输:打包成报文段、保证有序接收、重复报文被自动丢失
  4. 流量缓冲:解决速度不匹配的问题
  5. 可靠的传输服务(保证可达、丢包时通过重发时延实现可靠性)
  6. 拥塞控制

通过四元组实现面向连接(源地址、源端口、目标地址、目标端口)

TCP三次握手

image.png
大写的都是标志位,标志这个报文的类型 。小写seq是报文序列号,ack是确认序列号也是希望下一个报文的起始序列号。

syn洪泛攻击

攻击者通过发送大量的TCP SYN包,服务器返回ACK之后,不回应。
此时TCP连接处于挂起状态,服务器收不到客户端的ACK还会不断的发送ACK,占用服务器资源。
如果有大量被挂起的连接,服务器资源枯竭,导致正常连接无法握手。

为什么是三次?

为了保证可靠性,TCP的每一次消息都要确保正常收发。
三次才能验证双方的发送与接受的能力。
第一次握手成功后,服务端知道了客户端的发送能力。
第二次握手之后,客户端知道服务端能够正常接收到数据,也能正常发送。
第三次握手,服务端才能知道客户端能够正常接收数据。
如果没有了第三次,假设第二次握手的时候,服务端直接进入就绪状态。那么如果第二次握手失败,客户端还在等待回执,服务端却已经准备好,那么场面就陷入了尴尬。

如果第三次握手包丢失怎么样?

服务端处于SYN_REVD状态下,根据超时重传机制,重新发送确认报文,重传好几次还是没有成功,就关闭。
客户端此时在就绪状态,开始发送数据,但是服务端会返回RST包,客户端就知道有问题。释放连接,重新建立。

TCP四次挥手

image.png

为什么要四次挥手?

客户端发起关闭连接请求,服务端回复确认,仅代表客户端没有数据发送了。
但是,服务端还有数据没有发送完成,所以等 服务端数据发送完,服务端发起关闭连接请求,客户端确认后才确定可以关闭这次连接。

为什么在TIME-WAIT阶段必须等待2MSL时间?

MSL也就是报文生存的最大时间,超过这个时间的报文将丢弃。
如果客户端在发送最后一次握手的确认报文的时候就进入了closed状态。
如果最后一次报文丢失了,服务端要发起超时重传,但是重传的FIN报文永远不可能得到回应,服务端就不会释放。

总结

  1. TCP提供连接,让双方的传输更加稳定、安全
  2. TCP没有直接提供会话,因为应用对会话的需求多种多样,比如聊天程序会话在保持双方的聊天记录,电商程序会话在保持购物车、订单一致,所以会话通常在TCP连接上进一步封装,在应用层提供
  3. TCP是一个面向连接的协议,说的就是TCP协议参与的双方在收发数据之前会先建立连接。UDP是一个面向报文的协议—协议双方不需要建立连接,直接传送报文
  4. 连接需要消耗更多的资源

    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出现粘包的原因是多方面的,可能是来自发送方,也可能是来自接收方。

  1. 发送方原因
    1. TCP默认开启了Nagle算法(主要作用:减少网络中报文段的数量),而Nagle算法主要做两件事:
      1. 只有上一个分组得到确认,才会发送下一个分组;
      2. 收集多个小分组,在一个确认到来时一起发送。
        Nagle算法导致发送方可能会把多个间隔较小、数据量小的数据包,合并成一个大的数据包,然后进行封包一次性发送出去,从而导致粘包问题
  2. 接收方原因

    1. TCP接收到数据包时,并不会马上交到应用层进行处理,或者说应用层并不会立即处理。实际上,TCP将接收到的数据包保存在接收缓冲区里,然后应用程序主动从接受缓冲区读取数据。这样一来,如果TCP接收并存放数据包到缓冲区的速度大于应用程序从缓冲区读取数据包的速度,缓冲区就会存在多个首尾相接在一起的数据包,因此应用程序就有可能读取到多个粘到一起的包。

      UDP协议

      UDP协议是面向报文传输的

      校验和(checksum)机制

      校验数据在传输过程中有没有丢失、损坏是一个普遍需求。接收方可以通过校验和以及数据计算新的校验和的对比,分析出数据是否有出错。

      UDP和TCP区别

  3. 目的

    1. TCP提供可靠的网络传输
    2. UDP提供报文交换能力基础上,尽可能地简化协议轻装上阵
  4. 可靠性
    1. TCP保证可靠性
    2. UDP只管发送报文
  5. 有无连接
    1. TCP有连接
    2. UDP无连接,只发送数据
  6. 流控技术
    1. TCP在发送缓冲区中存储数据,在接收缓冲区中接收数据
    2. UDP无相关技术
  7. 传输速度
    1. UDP传输速度快,因为协议简化,封包小,没有连接和可靠性检查
  8. 场景差异
    1. TCP不适合高速数据传输场景