看了许多TCP三次握手的介绍,综合一下自己的理解方法,供大家参考:
client--客户端---主动发握手请求一方。
server----服务端----被动握手一方。
当client需要与server建立TCP连接时,发起握手请求。
第一次握手
前言:tcp协议会为每一个连接建立一个缓存区,放置自己刚发的报文信息,以方便对方没收到时重传,
第一次握手前,tcp为此连接建立一个空的缓存器,然后发第一个SYN包(可以理解为请求包或者同步包),此包的包头控制数据中的SYN位----置1,ack位为0(用来标识确认序列号无效),随机一个初始序列号ISN=10000(假设的,有机制计算初始序列号。是另一个问题,不介绍),确认序列号=0(tcp机制要求为0,无任何意义),且此包不能带数据。发给server。
第二次握手:
server的TCP协议收到包后,拆包看到SYN=1,ack=0,知道这是个请求建立连接的报文,SYN的设置就是用在此处作为判断依据的。
然后server同意连接,不同意的话不赘述了。server的tcp协议要回ACK包,就把ACK置1 ,确认序列号=10000+1(tcp协议中确认号总是跟随收到的序列号变化的。通常=收到的序列号+收到的包中数据段的字节数,此处无数据或数据=0,按道理应该+0,好多介绍说此处用掉一个序列号,就是为了确认号和收到的序列号不同),准备发包给client。
server此时也要发一个SYN请求建立连接的报文,TCP连接是双向的就体现在这里。server的tcp协议先置位SYN=1,然后初始化序列号=5000(假设的)。准备发包给client
此处在理论上发两个包的,那样好理解。实际是只发一个包。ack=1,SYN=1, 序列号=5000,确认序列号=10001。不带数据部分只有头部的包,一般20字节。
第三次握手:
client收到包后,tcp协议拆包检查,发现SYN=1知道是个请求建立tcp连接的包。再看ACK=1,确认序列号=我发出的序列号+1,就能判断是给我的SYN的回包。随即把自己的缓存中的SYN包删除。单向连接建立。然后回包给server,同意server的tcp连接请求。此时置位SYN=0,ACK=1。序列号=10001,确认序列号=5001(又浪费一个序列号)。发包给server。server收到包后也建立一个单向连接,这样双向连接就建立完成了。
为什么三次握手,不直接两次就OK的原因是
如果链路延迟过大,第一次握手的包对方没收到,超时了,client会再发一次请求,server没有机制判断是同一个连接发的两次请求,两次都会回包。client收到先到达的ACK包检查完头部信息后就删除了缓存的SYN包。第二个包延迟到达的ACK就因找不到对应的发送SYN对比而丢弃且不做任何回应,server只会建立第一次ACK的那个连接。另一个会因为ACK延迟而自动取消连接。三次连接保证了连接的唯一性。
为什么不四次握手,能省就省,没必要四次。
缓存机制在tcp中处处用到,tcp是面向连接的,可靠的传输协议。基本对每个发出的包都缓存,除非缓存满了,收到ACK后才删除对应包,否则到了一定时间会自动判断为包丢失,会自动再次发没收到ACK的包。