TCP初始化连接三次握手吧:发SYN包,然后返回SYN/ACK包,再发ACK包,连接正式建立。
但是这里有点出入,当请求者收到SYS /ACK包后,就开始建立连接了,而被请求者第三次握手结束后才建立连接。
关闭连接要四次握手:发FIN包,ACK 包,FIN包,ACK包,四次握手!!
一、建立TCP连接
1、客户端发送SYN报文(SYN为1) ,指明客户打算连接的服务器端口,以及初始化顺序号(ISN)
2、服务端发回包含服务器的初始顺序号的SYN报文段(SYN为1)。 同时,将确认号设置为客户的ISN加1以对客户的SYN报文段进行确认(ACK为1)
3、客户端将确认号设置为服务器的顺序号(ISN)+1对服务器的SYN报文段进行确认(ACK为1)
这三个报文段完成连接的建立,这个过程也称为三次握手。
------------------------------------------------------------------------
同时打开
两个应用程序同时彼此执行主动打开的情况是可能的,尽管发生的可能行极小。每一方必须发送一个SYN,且这些SYN必须传递给对方。这需要每一方使用一个对方熟知的端口作为本地端口。这又称为同时打开。
TCP是特意设计为了可以处理同时打开,对于同时打开它仅建立一条连接,而不是两条连接。
(1)当出现同时打开情况时,两端几乎同时发送SYN,并进入SYN_SENT状态;
(2)当每一端收到SYN时,状态变为SYN_RCVD,同时它们都再发SYN并对收到的SYN进行确认;
(3)当双方都收到SYN及相应的ACK时,状态都变迁为ESTABLISHED。
一个同时打开的连接需要交换4个报文段,比正常的三次握手多一个。此外,不要注意的是,没有将任何一端称为客户或服务器,因为每一端既是客户又是服务器。
------------------------------------------------------------------------
二、关闭一个TCP连接
TCP建立起来后,就可以在两个方向传送数据流。 当TCP的应用进程在没有数据需要发送时,就发送关闭命令。
TCP通过发送控制位FIN=1的数据片来关闭本方数据流,但是还可以继续接收数据,直到对方关闭那个方向的数据流,连接就关闭。
要终止一个连接要经过4次握手,因为TCP的半关闭(half-close)造成的。由于一个TCP连接是全双工(即数据在两个方向上能同时传递),因此两个方向必须单独的进行关闭。
关闭的原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向连接。当一端收到一个FIN,它必须通知应用层另一端已经中止了那个方向的数据传送,发送FIN通常是应用层进行关闭的结果。
TCP连接关闭有三种情况:
1、本方启动关闭
收到本方应用进程的关闭命令后,TCP在发送完尚未处理的报文段后,发FIN=1的报文段给对方,且TCP不再受理本方应用进程的数据发送。
在FIN以前发送的数据字节,包括FIN,都需要对方确认,否则要重传。注意FIN也要占一个顺序号。一旦收到对方对FIN的确认以及对方的FIN报文段,本方TCP就对该FIN进行确认,在等待一段时间,然后关闭连接。等待是为了防止本方的确认报文丢失,避免对方的重传报文干扰新的连接。
2、对方启动关闭
当TCP收到对方发来的FIN报文时,发ACK确认此FIN报文,并通知应用进程连接正在关闭。应用进程将以关闭命令响应。TCP在发送完尚未处理的报文段后,发一个FIN报文给对方TCP,然后等待对方对FIN的确认,收到确认后关闭连接。若对方的确认未及时到达,在等待一段时间后也关闭连接。
3、双方同时启动关闭
连接双方的应用进程同时发送关闭命令,则双方TCP在发送完尚未处理的报文段后,发送FIN报文。各方TCP在FIN前所发报文都得到确认后,发ACK确认他收到的FIN。各方在收到对方FIN的确认后,同样等待一段时间后在关闭连接。这称之为同时关闭。
------------------------------------------------------------------------
同时关闭
双方都执行主动关闭是可能的,TCP协议也允许这样的同时关闭。
(1)当应用层发出关闭命令时,两端均从ESTABLISHED变为FIN_WAIT_1;
(2)这将导致双方各发送一个FIN,两个FIN经过网络传输后分别到达另一端;
(3)收到FIN后,状态由FIN_WAIT_1变迁到CLOSING,并发送最后的ACK;
(3)当收到ACK时,状态变化成TIME_WAIT。
------------------------------------------------------------------------
三、TCP有限状态机
客户端TCP状态迁移:
CLOSED -> SYN_SENT -> ESTABLISHED -> FIN_WAIT_1 -> FIN_WAIT_2 -> TIME_WAIT -> CLOSED
服务器TCP状态迁移:
CLOSED -> LISTEN -> SYN_RECEIVED -> ESTABLISHED -> CLOSE_WAIT -> LAST_ACK -> CLOSED
(1)CLOSED
状态时初始状态。关闭状态,没有连接活动或正在进行
(2)LISTEN:被动打开,服务器端的
状态变为LISTEN(监听)。
被动打开的概念:连接的一端的应用程序通知操作系统,希望建立一个传入的连接。这时候操作系统为连接的这一端建立一个连
接。
与之对应的是主动连接:应用程序通过主动打开请求来告诉操作系统建立一个连接。
(3)SYNRECVD:服务器端收到SYN后,状态为SYN;发送SYN
ACK;
(4)
SYN_SENTY:应用程序发送SYN后,状态为SYN_SENT;
(5)ESTABLISHED: SYNRECVD收到ACK后,状态为ESTABLISHED;
SYN_SENT在收到SYN ACK,发送ACK,状态为ESTABLISHED;
(6)FIN_WAIT_1:(主动关闭)应用程序端发送FIN,准备断开TCP连接;状态从ESTABLISHED——>FIN_WAIT_1;
(7)FIN_WAIT_2:(主动关闭)应用程序端只收到服务器端的ACK信号,并没有收到FIN信号;说明服务器端还有数据传输,那么此时为半连接;
(8)TIME_WAIT:有两种方式进入 该状态:
1、FIN_WAIT_1进入:此时应用程序端口收到FIN+ACK(而不是像FIN_WAIT_2那样只收到ACK,说明数据已经发送完毕)并
向服务器端口发送ACK;
2、FIN_WAIT_2进入:此时应用程序端口收到了FIN,然后向服务器端发送ACK;TIME_WAIT是为了实现TCP
全双工连接的可靠性关闭,用来重发可能丢失的ACK报文;需要持续2个MSL(最大报文生存时间):假设应用程序端口在进入TIME_WAIT后,2个
MSL时间内并没有收到FIN,说明应用程序最后发出的ACK已经收到了;否则,会在2个MSL内在此收到ACK报文;
(9) CLOSE_WAIT:(被动关闭)服务器端在收到FIN后,发送ACK,状态为CLOSE_WAIT;如果此时服务器端还有数据需要发送,那么就发送,直到数据发送完毕;此时,服务器端发送FIN,状态变为LAST_ACK;
(10)LAST-ACK: (被动关闭)当被动关闭的一方在发送FIN报文后,等待对方的ACK报文的时候,就处于LAST_ACK
状态。当收到对方的ACK报文后,也就可以进入到CLOSED 可用状态了。