zoukankan      html  css  js  c++  java
  • TCP 3-Way Handshake

    TCP是面向连接的协议,其数据传输过程分为建立连接、数据传送、释放连接三个阶段。

    0 建立连接

    建立连接的过程也就是常说的“三次握手”:

    • 客户端向服务器端发送一个SYN报文(SYN=1表示这是一个连接请求或连接接收报文),并随机选取一个起始序号x;
    • 服务器端应答一个SYN报文,同时ACK(确认位)置1【ACK=1时TCP报文段首部中的ack(确认号字段)才有效】,随机选取一个服务器端的起始序号y,并将ack字段设为x+1,表示已经收到客户端发来的SYN报文,期待收到序号为x+1的下一个报文;
    • 客户端应答一个ACK报文,将序号设为x+1,并且ack字段设为y+1,表示已经收到服务器端的SYN报文,期待收到序号为y+1的下一个报文。
      注:序列号seq也称ISN(Initial Sequence Number)
      图片来自百度
      之所以要采用三次握手机制而不是两次或四次,要从握手机制的目的说起:
      握手主要是为了确认双方的发送、接收能力是否正常,顺带初始化序号seq,为以后的数据传送做好准备,所以:
      第一次握手:服务器收到客户端发来的网络包,服务器就明白客户端的发送能力、服务器的接收能力正常;
      第二次握手:服务器发包,客户端收到后,客户端就明白服务器的发送、接收,客户端的发送、接收都是正常的;
      二次握手后,客户端倒是全明白了,但是服务器端无法确认客户端能否正常接收、服务器是否正常发送,所以两次握手不够;
      第三次握手:服务器收到客户端发送的网络包,服务器确认了自己上次的发送正常、客户端接收也正常,所以四次握手是多余的。

    1 补充问题

    • 序列号(ISN)之所以随机生成,是为了避免被攻击(若固定,则下一次传送的ack就显而易见);
    • 前两次握手不可以携带数据,第三次可以携带。第一次握手服务器端接收能力未知,如果携带数据就可能丢失。第二次客户端接收能力未知,如果携带数据也可能丢失。第三次客户端知道服务器接收正常,并且自己已经处于ESTABLISHED状态;
    • 服务器发出SYN报文后,处于SYN-RCVD状态,此时不同的连接请求会被放在半连接队列里,三次握手完成后的连接请求被放在全连接队列里。

    2 连接释放

    连接释放的过程也就是常说的“四次挥手”:
    P.S. 图中以客户端发起释放请求为例

    1. 客户端发送释放请求,将FIN(终止位)置1,表示客户端已经发完数据,请求释放;
    2. 服务器发一个ACK报文,确认号ack为u+1,这时从客户端到服务器的连接被释放,处于半关闭状态
    3. 如果服务器也要断开连接,就向客户端发送连接释放报文(FIN=1);
    4. 客户端发送一个应答报文,序列号seq为u+1,等待一段时间(2MSL)确保服务器收到ACK报文,之后关闭连接。

    图片源自百度
    客户端之所以要等待2MSL时间才关闭,有两个原因:

    • 一旦服务器没有收到ACK报文,服务器就会重发FIN报文,客户端再次收到FIN报文,就知道之前发送的ACK报文丢失,会重置时间等待计时器为2MSL并重传ACK报文。
      如果没有这段等待时间,万一服务器没有正常接收ACK报文,接下来重传的FIN报文段就无法到达客户端,服务器无法正常关闭。
    • 客户端发完最后一个ACK报文,经过2MSL,本次连接产生的报文都会从网络中消失,避免下一次新连接出现本次旧的连接请求报文段。
  • 相关阅读:
    第二阶段冲刺进程2
    第二阶段冲刺进程1
    Alpha版使用说明
    回复每组的意见的评价
    每个组针对本组提出的意见的整理
    软件项目第一次Sprint总结
    站立会议7
    站立会议6
    团队博客11
    团队博客10
  • 原文地址:https://www.cnblogs.com/EIMadrigal/p/11560205.html
Copyright © 2011-2022 走看看