传输层2.三次握手TCP连接

1.TCP三次握手过程和状态变迁

TCP是面向连接的协议,所以使用TCP前必须先建立连接,而建立连接是通过三次握手来进行的。

传输层2.三次握手TCP连接

  • 一开始,客户端和服务端都处于CLOSED状态。先是服务端主动监听某个端口,处于LISTEN状态
  • 客户端会随机初始化序号client_isn,将此序号置于TCP首部的序号字段中,同时把SYN标志位置为1,表示SYN报文。客户端向服务端发送第一个SYN报文,表示向服务端发起连接,该报文不包含应用层数据,之后客户端处于SYN-SENT状态。
  • 服务端收到客户端的SYN报文后,首先服务端也随机初始化自己序列号server_isn,将此序列号填入TCP首部的序号字段中,其次把TCP首部的确认应答号字段填入client_isn+1,接着把SYN和ACK标志位置为1。最后把该报文发给客户端,该报文也不包含应用层数据,之后服务端处于SYN_RCVD状态。
  • 客户端收到服务端报文后,还要向服务端回应最后一个应答报文,首先该应答报文的首部ACK标志位置为1,其次确认应答号字段填入server_isn+1,最后把报文发送给服务端,这次报文可以携带客户到服务器的数据,之后客户端处于ESTABLISHED状态。
  • 服务器收到客户端的应答报文后,也进入ESTABLISHED状态。

从上面的过程可以发现第三次握手是可以携带数据的,前两次握手是不可以携带数据的。
一旦完成三次握手,双方都处于ESTABLISHED状态,此时连接就已经建立完成,客户端和服务端就可以相互发送数据了。

2.如何在Linux系统中查看TCP状态

TCP的连接状态查看,在Linux可以通过netstat-napt命令查看。
传输层2.三次握手TCP连接

3.为什么是三次握手?不是两次、四次?

  1. 三次握手才可以阻止重复历史连接的初始化(主要原因)
  2. 三次握手才可以同步双方的初始化序列化。序列号能保证数据包不重复、不丢弃和按序传输。
  3. 三次握手才可以避免资源浪费

为什么不是两次、四次:

  • 两次:无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号。
  • 四次:三次握手就已经理论最少可靠连接建立,所以不需要使用更多的通信次数。

4.为什么客户端和服务端的初始序列号ISN是不相同的?

  1. 如果序列号相同就无法分辨历史报文。
  2. 同时为了安全性,防止黑客伪造相同序列号的TCP报文被对方接收。

5.既然IP层会分片,为什么TCP层还需要MSS呢

传输层2.三次握手TCP连接

  • MTU:一个网络包的最大长度,以太网中一般为1500字节。
  • MSS:除去IP和TCP头部之后,一个网络包所能容纳的TCP数据的最大长度

如果只进行IP层以MTU大小进行分片,如果其中一个IP分片丢失,整个IP报文的所有分片都需要重传。
并且因为IP层没有超时重传机制,所以需要TCP层发起超时重传。这样的效率很低。
因此为了达到最佳的传输效能,建立连接的时候通常需要协商双方的MSS值,当TCP层发现数据超过MSS时,则就会先进行分片,在这个基础上就不需要进程IP分片了。
经过TCP层分片后,如果一个TCP分片丢失,进行重发时也是以MSS为单位,而不用重传所有的分片,大大增加了重传的效率。

6.什么是SYN攻击?如何避免SYN攻击

攻击者短时间伪造不同IP地址的SYN报文,服务端每接到一个SYN报文,就进入SYN_RCVD状态,当服务端发送出去的ACK+SYN报文,无法得到未知IP主机的ACK应答,久而久之就会占满服务端的SYN接收队列(未连接队列)使得服务器不能为正常用户服务。

避免:

  1. 修改Linux内核参数,控制队列大小和当队列满时应当做什么处理
    • 当网卡接收数据包的速度大于内核处理的速度时,会有一个队列保存这些数据包。控制该队列的最大值如下参数:
      net.core.netdev_max_backlog
    • SYN_RCVD状态连接的最大个数
      net.ipv4.tcp_max_syn_backlog
    • 超出处理能时,对新的SYN直接回报RST,丢弃连接:
      net.ipv4.tcp_abort_on_overflow
  2. 通过cookie值,直接将SYN+ACK值返回给服务端处理,如果服务端确认ACK合法,建立连接。
上一篇:element-ui中el-date-picker时间选择器限制选择7天内数据、获取某一天0点或23:59:59


下一篇:BIO和NIO有啥区别