TCP的连接建立:三次握手
最初两边TCP进程都处于CLOSED(关闭状态)。A主动打开连接,B被动打开连接。
B的TCP服务器进程创建传输控制块TCB(Transmission Control Block),然后处于LISTEN(监听状态),准备接受客户端的连接请求。
1.A的TCP客户端进程也创建传输控制块TCB,向B主动发起连接报文段,此时报文段中SYN=1,随机选择一个初始序列号,seq=x,TCP规定SYN=1时不能携带数据,但要消耗一个序号,因此声明自己的序号是 seq=x.此时A进入SYN_SENT(同步已发送)状态。
2.B收到连接请求后,如果同意连接,则向A发送确认报文段,确认位ACK=1,确认号为ack=x+1,同时A也要连接B,所以发送SYN=1,同时选择一个初始序号seq=y。此报文段不能携带数据,但同样要消耗一个序列号。此时B处于SYN_RCVD(同步收到)状态
3.A收到B的确认报文后,也要给B发送确认报文,此报文段中,ACK=1,ack=y+1;seq=x+1;TCP规定ACK可以携带数据,如果不携带数据则不消耗序列号,所以下一个数据报文段的序号还是x+1,此时A进入ESTABLISHED(已建立连接)状态。
当B收到A的确认报文后处于ESTABLISHED(已建立连接)状态。
TCP释放连接:四次挥手
1.A向B发送连接释放报文段并停止发送数据,此报文段中FIN=;seq=u(等于上次发送数据的最后一个字节加1),此时A进入FIN_WAIT-1(终止等待1)状态。TCP规定,FIN报文段即使不携带数据也要消耗一个序号。
2.B收到连接释放报文段后就发送确认报文,此时ACK=1;ack=u+1;seq=v;此时B进入close_wait(关闭等待)状态。TCP服务器进程通知应用进程A到B的连接释放了,此时TCP连接处于半关闭状态,B到A的连接并未断开,此时B发送数据A仍要接收。
A收到B的确认报文后就处于FIN_WAIT2状态,等待B发送连接释放报文段。
3.如果B没有数据要发送了,就发送连接释放报文段,此时,FIN=1;ACK=1;seq=w;ack=u+1;此时B处于last_ack(最后确认)状态。
4.A收到B的连接请求报文段后就发送确认报文段,此时ACK=1;ack=w+1;seq=u+1;此时A处于time_wait等待状态。
此时TCP连接还未释放掉,必须经过时间等待计时器(TIME-WAIT timer)设置的2倍的最长报文寿命MSL(Maximum Segment Lifetime)后A才进入到CLOSED,MSL建议设为2分钟。当A撤销相应的传输控制块TCB后,就结束了这次TCP连接。
B收到A的确认报文就进入CLOSED状态,当B撤销相应的传输控制块TCB后,就结束了这次TCP连接。
设置TIME_WAIT的意义:
1.保证A发送的最后一个确认报文ACK能够到达B。因为这个ACK报文有可能丢失,B收不到这个FIN+ACK的报文的确认,所以B就会超时重传这个FIN+ACK报文段,这样A就能在2MSL时间内接受到B重新发来的FIN+ACK报文段,接着A再重传一次确认报文,重新启动时间等待计时器。
2.A在发送完最后一个ACK后,经过2MSL后,就可以使本连接持续的时间所产生的报文段都从网络中消失。
为什么是三次握手:
如果两次握手的话会出现几率比较大的浪费ser的资源
①假设cli发送连接请求报文后就因为问题而导致下线。之后B收到A发送的连接请求,给A发送确认报文,同意建立连接,此时假定在两次握手的前提下,连接建立成功,这样会导致ser的资源白白浪费。
②假设在两次握手的前提下,A发送的第一个连接请求报文段在某一网络结点长时间滞留,以致连接释放后才到达B,B收到A的连接请求报文段后认为A又一次发起的连接,于是向A发送确认报文,同意连接。连接建立成功,这样会白白浪费B的资源。
为什么是四次挥手
TCP协议是全双工通讯,在建立连接时,建立的双向连接,客户端和服务器可以给彼此发送数据,所以在释放连接的时候是需要两边都进行确认的。
在三次挥手的情况下,首先释放掉A到B的连接,此时TCP处于半关闭状态(half_Close),A不能向B发送数据,但B可向A发送数据,此时A收到B的确认报文后,立即给B发送确认报文段,这样会导致B还在向A发送数据时就已经关闭连接了。
但如果B刚好没有数据要传送了。三次挥手是可以的
附上一张三次握手与四次挥手的全过程图