npm更新依赖、版本等命令使用

TCP基本认识

什么是TCP

  • TCP头格式有哪些

    TCP 头格式
    • 序列号:每个TCP都有一个标识,通过SYN包传给接收端,每发送一次数据,就累加数值,目的是防止TCP在网络中乱序。

    • 确认应答号:确认应答号表示下一个分配的序列号,接收端主机收到确认应答号,表示收到该应答号之前的网络包。目的是解决TCP包在网络中丢失的问题。

    • 控制位

      ACK:ACK为1,表示收到之前的消息,确认应答位有效。

      RST:RST为1,表示发生异常,连接强制中断。

      SYN:SYN为1,表示建立连接,序列化进行初始化。

      FIN:FIN为1,表示希望关闭连接,之后不会有数据发送。

  • 为什么要用TCP

    TCP工作在传输层,主要解决包在网络中可靠传输的问题(无损、有序)。

  • 什么是TCP/TCP连接呢?

    TCP有三个关键词:面向连接、可靠传输、字符流

    • 面向连接是指TCP必须在两端之间建立一对一连接才可以通信。

    • 可靠传输是指TCP在网络中不会丢失,一定会到达另一方。

    • 字符流是指TCP会把报文拆分,通过消息的边界来判断有效的用户消息。

    TCP连接是指客户端和服务端达成三个信息的共识,就叫建立了连接。

    • Socket:有IP地址和端口号组成
    • 序列号:解决乱序问题。
    • 窗口大小:流量控制。
  • 确认一个唯一的TCP连接

    TCP四元组可以确认一个唯一的TCP连接【目的端口、目的地址;源地址、源端口】

    其中源地址、目的地址在IP头部,用来确认报文发送给网络中的哪个主机。

    而源端口、目的端口在TCP头部,用来确认报文发送给主机中的哪个进程。

    最大TCP连接数 = IP数 x 端口数,当然,这只是理论值,实际还受两个方面的影响:

    • 文件描述符:TCP连接本质是一个文件,受文件描述符上限的控制
    • 内存限制:每个TCP连接都要占用一定内存。

TCP/UDP

  • UDP和TCP有什么区别?应用场景?

    UDP是不可靠传输,并且是无连接的,也就是不依靠连接来传输数据,不止可以进行一对一,还可以一对多发送数据。

    UDP的头部没有首部字段,因为UDP的首部大小是固定的,而TCP因为还有选项字段,首部大小不固定。

    分片不同

    • TCP 的数据大小如果大于 MSS 大小,则会在传输层进行分片,目标主机收到后,也同样在传输层组装 TCP 数据包,如果中途丢失了一个分片,只需要传输丢失的这个分片。
    • UDP 的数据大小如果大于 MTU 大小,则会在 IP 层进行分片,目标主机收到后,在 IP 层组装完数据,接着再传给传输层。

    应用场景:UDP:DNS、视频等媒体;TCP:HTTP/HTTPS、文件传输。

  • TCP和UDP的端口可以使用同一个吗?

    可以使用一个,端口只不过是用来表示同一个主机中的不同进程的。传输层的端口号,用来表示主机上的不同程序的数据包。

    当主机收到数据包后,可以在 IP 包头的「协议号」字段知道该数据包是 TCP/UDP,所以可以根据这个信息确定送给哪个模块(TCP/UDP)处理,送给 TCP/UDP 模块的报文根据「端口号」确定送给哪个应用程序处理。

TCP连接建立

TCP 的连接状态查看,在 Linux 可以通过 netstat -napt 命令查看。

三次握手

  • 三次握手的过程

    首先,TCP三次握手是为了保证客户端和服务器之间的连接是可靠的,并且可以传输数据。

    第一次握手(SYN):客户端向服务端发送SYN(同步)标志的TCP数据包,并指定客户端的初始化序列号(ISN)。

    第二次握手(SYN + ACK):服务端收到客户端发送的包后,会向客户端发送一个带有SYN + ACK(确认)标志的数据包,同时指定服务器的初始化序列号(ISN)。

    第三次握手(ACK):客户端收到服务器发送的包后,向服务器发送带有ACK标志的包作为响应,表示客户端已经收到了服务器的响应,建立连接成功。

    TCP 三次握手
  • 为什么是“三次”

    1. 首要原因是可以阻止旧的重复连接初始化造成混乱。

      如果客户端发送SYN报文(10),网络阻塞,客户端又发送一个SYN报文(20),此时SYN为10的报文到达。

      服务端返回ACK,报文确认序列号为11,不是客户端想要的连接(想要21),客户端就发送RST中止连接。这样就防止了旧的连接初始化。

      • 如果是两次握手,服务端返回ACK后就建立了连接,发送了数据,就浪费了资源。
    2. 可以同步双方初始序列号。

      通过初始序列号,就可以知道发送出去的信息,哪些已经被对方收到。就要通过三次的一来一回,才能确保双方的初始化序列号被同步。

      而两次握手只保证了一方的初始序列号能被对方成功接收,没办法保证双方的初始序列号都能被确认接收。

    3. 避免资源浪费。

      如果SYN报文阻塞,客户端重复发送多次SYN报文,那么服务端就会在收到请求后建立多个冗余的无效连接,造成资源浪费。

连接建立

  • 初始化序列号为什么要随机

    如果每次建立连接,客户端和服务器的初始化序列号都一样,很容易出现历史报文被下一个TCP连接接收的问题。

  • 怎么随机序列号

    RFC793 提到初始化序列号 ISN 随机生成算法:ISN = M + F(localhost, localport, remotehost, remoteport)。与计时器还有Hash算法有关,

    由于随机数是会基于时钟计时器递增的,基本不可能会随机成一样的初始化序列号。

  • IP会分片,为什么需要MSS?

    MTU:网络包的最大长度,一般为1500字节。

    MSS:除去IP和TCP头部,一个网络包能容纳的最大TCP数据长度。

    MTU 与 MSS

    如果IP层有超过MTU大小的数据,IP层就会进行分片,来保证每一片的长度小于MTU。

    如果把TCP的分片交给IP,如果一个IP分片丢失,整个IP报文的所有分片都要重传。所以为了达到最佳的传输效率,TCP协议在建立连接时,通常要协商双方的MSS值,当 TCP 层发现数据超过 MSS 时,则就先会进行分片,当然由它形成的 IP 包的长度也就不会大于 MTU ,自然也就不用 IP 分片了。

    经过 TCP 层分片后,如果一个 TCP 分片丢失后,进行重发时也是以 MSS 为单位,而不用重传所有的分片,大大增加了重传的效率。

握手丢失

  • 第一次握手(SYN)丢失

    客户端迟迟收不到ACK,触发超时重传机制,而且重传的SYN报文的序列号是一样的。

    在 Linux 里,客户端的 SYN 报文最大重传次数由 tcp_syn_retries内核参数控制,这个参数是可以自定义的,默认值一般是 5。

    一般超时重传的等待时间为上一次超时时间的二倍。

  • 第二次握手(SYN+ ACK)丢失

    可能会让客户端以为自己的SYN丢失,并且服务端认为自己的SYN + ACK丢失,服务端和客户端都会重传

    • 客户端会重传 SYN 报文,也就是第一次握手,最大重传次数由 tcp_syn_retries内核参数决定;
    • 服务端会重传 SYN-ACK 报文,也就是第二次握手,最大重传次数由 tcp_synack_retries 内核参数决定。
  • 第三次握手(ACK)丢失

    ACK报文不会重传,ACK报文丢失,服务端重传对应的SYN报文。

SYN攻击

  • 什么是SYN攻击?如何避免?

    • SYN攻击原理:

      攻击者伪造不同IP地址的SYN报文请求连接,服务端收到连接请求后分配资源,回复

      ACK+SYN包,但是由于IP地址是伪造的,无法收到回应,久而久之造成服务端半连接队列被占满,无法正常工作。

    • 预防SYN攻击的方法:

      • 增大半连接队列

        要想增大半连接队列,我们得知不能只单纯增大 tcp_max_syn_backlog 的值,还需一同增大 somaxconn 和 backlog,也就是增大全连接队列

        tcp_max_syn_backlog(最大TCPSYN队列积压):处于SYN_RECV的TCP最大连接数

      • 开启tcp_syncookies功能

        开启 syncookies 功能就可以在不使用 SYN 半连接队列的情况下成功建立连接

        当半连接队列满了,开启这个功能可以让后续连接不进入半连接队列,而是计算一个cookie,作为请求报文序列号发给客户端,如果服务器端收到客户端确认报文,会检查ack包合法性,如果合法,直接加入到accept队列。

        开启 syncookies 功能
      • 减少SYN + ACK 重传次数

        当服务端受到 SYN 攻击时,就会有大量处于 SYN_RECV 状态的 TCP 连接,处于这个状态的 TCP 会重传 SYN+ACK ,当重传超过次数达到上限后,就会断开连接。

        那么针对 SYN 攻击的场景,我们可以减少 SYN+ACK 的重传次数,以加快处于 SYN_RECV 状态的 TCP 连接断开。

        SYN-ACK 报文的最大重传次数由 tcp_synack_retries内核参数决定(默认值是 5 次),比如将 tcp_synack_retries 减少到 2 次

猜你喜欢

转载自blog.csdn.net/weixin_44126032/article/details/127281627
今日推荐