TCP

  1. 客户端通过向服务器端发送一个SYN来创建一个主动打开,作为三次握手的一部分。客户端把这段连接的序号设定为随机数 A。
  2. 服务器端应当为一个合法的SYN回送一个SYN/ACK。ACK 的确认码应为 A+1,SYN/ACK 包本身又有一个随机序号 B。
  3. 最后,客户端再发送一个ACK。当服务端受到这个ACK的时候,就完成了三路握手,并进入了连接创建状态。此时包序号被设定为收到的确认号 A+1,而响应则为 B+1。

    用处

    1. 确认双方的交付能力
    2. 指定初始序列号,为可靠传输做准备
    3. 交互加密机制

    相关问题

    1. ISN固定吗
    2. 半连接队列
    3. 握手过程可以携带数据吗

    四次挥手

    通俗的说法
    1)Client:我所有东西都说完了
    2)Server:我已经全部听到了,发个消息给你表示我收到了,但是等等我,我还没说完
    3)Server:好了,我已经说完了
    4)Client:好的,那我们的通信结束l

    挥手过程

    注意: 中断连接端可以是客户端,也可以是服务器端. 下面仅以客户端断开连接举例, 反之亦然.

  4. 客户端发送一个数据分段, 其中的 FIN 标记设置为1. 客户端进入 FIN-WAIT 状态. 该状态下客户端只接收数据, 不再发送数据.

  5. 服务器接收到带有 FIN = 1 的数据分段, 发送带有 ACK = 1 的剩余数据分段, 确认收到客户端发来的 FIN 信息.
  6. 服务器等到所有数据传输结束, 向客户端发送一个带有 FIN = 1 的数据分段, 并进入 CLOSE-WAIT 状态, 等待客户端发来带有 ACK = 1 的确认报文.
  7. 客户端收到服务器发来带有 FIN = 1 的报文, 返回 ACK = 1 的报文确认, 为了防止服务器端未收到需要重发, 进入 TIME-WAIT 状态. 服务器接收到报文后关闭连接. 客户端等待 2MSL 后未收到回复, 则认为服务器成功关闭, 客户端关闭连接.

四次挥手

TIME_WAIT

  • 确保服务器已经收到ACK报文
  • 持续时间至少为一个报文的来回时间
  • 如果没有这个状态会发生什么?
    • 同ip同端口再次建立起连接,并且原来的连接还残留有数据,这个时候会被新的连接所接收
  • 解决方法

    • 修改配置文件,现在最大连接数(/etc/security/limits.conf)
    • 修改默认的等待时间(/etc/sysctl.conf)。net.ipv4.tcp_fin_timeout=2
    • 允许重用端口:net.ipv4.tcp_tw_reuse=1
    • 开启快速回收策略:net.ipv4.tcp_tw_recycle=1

      Close_Wait状态

      1. 无论是time_wait还是close_wait滞留太多,我们可以通过so_ reuseaddr参数来强行重用端口

      与UDP的差别

  • UDP

    • 无连接
    • 不可靠
    • 面向报文(对上层来的报文不做拆分合并,只是封装上UDP首部)
    • 支持一对多,多对一
  • TCP

    • 面向连接的
    • 可靠的
    • 面向字节流的(把报文看成字节流,拆分组织成大小不等的数据块)
    • 只能一对一

      首部

  • 固定的20字节+4字节的(选项+ 填充)

  • RST报文
    • 访问的端口不存在
    • 访问的端口正处于 time_wait 状态
    • 异常终止
    • 处理半连接状态