创建TCP须要三次握手才能创建,而断开链接则须要四次挥手。服务器
TCP有6种标识:SYN(创建联机)、ACK(确认)、PSH(传送)、FIN(结束)、RST(重置)、URG(紧急)网络
客户端向服务端发送链接请求报文。这时,报文首部中的同步序号SYN=1,同时随机生成初始序列号seq=x。此时,TCP客户端进程进入了SYN_SENT(同步已发送状态)状态。3d
TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但须要消耗掉一个序号。这是三次握手中的开始,表示客户端想和服务端创建链接。cdn
服务端收到请求报文后,若是赞成创建链接,则发出确认报文。确认报文中SYN=1、ACK=1,确认序号ack=x+1,同时也为服务端随机初始化一个序列号seq=y。此时,服务端进程进入了SYN_RCVD(同步收到)状态。blog
这个报文也不携带数据,而且也要消耗掉一个序号。这个报文带有SYN(创建链接)和ACK(确认)标识。表示服务端询问客户端是否准备好链接。进程
客户端收到服务器发送的确认后,还要给服务端发送确认报文。确认报文中ACK=1、ack=y+1。此时,TCP链接创建,客户端进入ESTABLISHED(已创建链接)状态。资源
至此,客服端与服务端链接创建成功,能够互相通讯了。同步
在创建链接后,两台主机就能够相互传输数据了。如图所示: it
二、假设主机B在彻底成功接收数据的基础上,主机B为了确认这数据是否接收彻底,向主机A发送ACK包,并将Ack号设置为1301。io
确认Ack号公式:Ack号 = Seq号 + 传递的字节数 + 1
三、主机A得到B传来的Ack(1301)后,开始发送Seq为1301,滑动窗体为100的数据。
如此循环。。。直到数据所有发送完成。但这只是数据彻底发送正确的状况,假如某个数据包由于某种缘由丢失了,那又该如何呢?以下图所示
为了完成数据重传,TCP套接字每次发送数据包时都会启动定时器,若是在必定时间内没有收到目标机器传回的ACK确认包,那么当定时器超时时,数据包就会被重传。
客户端发送一个FIN(结束),用来关闭客户端与服务端之间的链接。
客户端进程发出链接释放报文,而且中止发送数据。释放数据报文首部中FIN=1,其序列号seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1)。此时,客户端进入FIN-WAIT-1(终止等待1)状态。
服务端收到这个FIN,服务端发回一个ACK(确认)报文,ACK=1、ack=u+1,而且带上本身的序列号seq=v。此时,服务端进入CLOSE-WAIT(关闭等待)状态。
服务端通知高层的应用进程,客户端向服务端的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据发送了,可是服务器若发送数据,客户端依然要接收。这个状态还要持续一段时间,这段时间就是CLOSE-WAIT状态持续的时间。
客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送链接释放报文。
服务端发送一个FIN(结束)到客户端,服务端关闭客户端的链接。
服务器将最后的数据发送完毕后,就向客户端发送链接释放报文,FIN=1、ack=w+1。因为在半关闭状态,服务器极可能又发送数据,假定此时的序列号为seq=w。此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
客户端发送ACK(确认)报文确认,并将确认的序号+1,关闭链接完成。
客户端收到服务器的链接释放报文后,必须发出确认,ACK=1、ack=w+1,本身的序列号seq=u+1。此时,客户端就进入了TIME-WAIT(时间等待)状态。
注意:此时TCP链接尚未释放,必须通过2MSL(最后报文段寿命)的时间后,没有收到服务器端的ACK,认为服务器端已经正常关闭链接,因而本身也关闭链接,进入CLOSED状态。
服务端在收到ACK确认报文后,就当即进入CLOSED状态。
假如客户端发送了第一个链接的请求报文,可是因为网络很差,这个请求没有当即到达服务端,而是在某个网络节点中滞留了,直到某个时间才到达服务端。
原本这已是一个失效的报文,可是服务端接收到这个请求报文后,仍是会向客户端发出确认的报文,表示赞成链接。
假如不采用三次握手,那么只要服务端发出确认,新的链接就创建了,但其实这个请求失效的,客户端并不会再向服务端发送确认信息。可是服务端认为链接已经创建,会一直等待客户端发送数据。这样,服务端的不少资源就白白浪费了,采用三次握手就是为了防止这种状况的发生。服务端会由于收不到客户端的确认报文,就知道客户端并无创建链接。
为了保证有效链接的创建,这就是三次握手的做用。
当关闭链接时,当收到客户端的FIN报文时,仅表示对方没有数据发送了,可是并不表明服务端自身的全部数据都传输完成了,因此不必定会立刻关闭链接。只有当服务端的数据发送完毕后,服务端再次发送FIN报文给客户端,来通知客户端赞成关闭链接。
因此服务端在收到客户端的FIN报文后,会发送一个ACK报文,表示确认收到关闭链接报文了,直到服务端报文数据传输完毕后,再发送FIN报文给客户端表示服务端赞成关闭了。所以会有四次挥手。