1、建设连贯协定(三次握手)
(1)客户端发送一个带SYN标记的TCP报文到服务器。这是三次握手过程中的报文1。
(2)服务器端回应客户端的,这是三次握手中的第2个报文,这个报文同时带ACK标记和SYN标记。因而它示意对方才客户端SYN报文的回应;同时又标识SYN给客户端,询问客户端是否筹备好进行数据通讯。
(3)客户必须再次回应服务段一个ACK报文,这是报文段3。
为什么须要“三次握手”
这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连申请后,它能够把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。
但敞开连贯时,当收到对方的FIN报文告诉时,它仅仅示意对方没有数据发送给你了;
但未必你所有的数据都全副发送给对方了,所以你可能不会马上敞开SOCKET,也即你可能还须要发送一些数据给对方之后,再发送FIN报文给对方来示意你批准当初能够敞开连贯了,所以它这里的ACK报文和FIN报文少数状况下都是离开发送的。
在谢希仁著《计算机网络》第四版中讲“三次握手”的目标是“为了避免已生效的连贯申请报文段忽然又传送到了服务端,因此产生谬误”。
在另一部经典的《计算机网络》一书中讲“三次握手”的目标是为了解决“网络中存在提早的反复分组”的问题。这两种不必的表述其实说明的是同一个问题。
2、连贯终止协定(四次挥手)
**因为TCP连贯是全双工的,因而每个方向都必须独自进行敞开**。这准则是当一方实现它的数据发送工作后就能发送一个FIN来终止这个方向的连贯。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连贯在收到一个FIN后仍能发送数据。首先进行敞开的一方将执行被动敞开,而另一方执行被动敞开。
(1) TCP客户端发送一个FIN,用来敞开客户到服务器的数据传送(报文段4)。(2) 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。和SYN一样,一个FIN将占用一个序号。
(3) 服务器敞开客户端的连贯,发送一个FIN给客户端(报文段6)。
(4) 客户段发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7)。
为什么须要“四次挥手”
那可能有人会有疑难,在tcp连贯握手时为何ACK是和SYN一起发送,这里ACK却没有和FIN一起发送呢。起因是因为tcp是全双工模式,**接管到FIN时象征将没有数据再发来,然而还是能够持续发送数据**。
握手,挥手过程中各状态介绍(详见wiki:TCP)
3次握手过程状态:
- LISTEN: 这个也是非常容易了解的一个状态,示意服务器端的某个SOCKET处于监听状态,能够承受连贯了。
- SYN_SENT: 当客户端SOCKET执行CONNECT连贯时,它首先发送SYN报文,因而也随即它会进入到了SYN_SENT状态,并期待服务端的发送三次握手中的第2个报文。SYN_SENT状态示意客户端已发送SYN报文。(发送端)
- SYN_RCVD: 这个状态与SYN_SENT遐想响应这个状态示意承受到了SYN报文,在失常状况下,这个状态是服务器端的SOCKET在建设TCP连贯时的三次握手会话过程中的一个中间状态,很短暂,基本上用netstat你是很难看到这种状态的,除非你特意写了一个客户端测试程序,成心将三次TCP握手过程中最初一个ACK报文不予发送。因而这种状态时,当收到客户端的ACK报文后,它会进入到ESTABLISHED状态。(服务器端)
- ESTABLISHED:这个容易了解了,示意连贯曾经建设了。
4次挥手过程状态:(可参考上图)
- FIN_WAIT_1: 这个状态要好好解释一下,其实FIN_WAIT_1和FIN_WAIT_2状态的真正含意都是示意期待对方的FIN报文。而这两种状态的区别是:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想被动敞开连贯,向对方发送了FIN报文,此时该SOCKET即进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,当然在理论的失常状况下,无论对方何种状况下,都应该马上回应ACK报文,所以FIN_WAIT_1状态个别是比拟难见到的,而FIN_WAIT_2状态还有时经常能够用netstat看到。(被动方)
- FIN_WAIT_2:下面曾经具体解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,示意半连贯,也即有一方要求close连贯,但另外还通知对方,我临时还有点数据须要传送给你(ACK信息),稍后再敞开连贯。(被动方)
- TIME_WAIT: 示意收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带FIN标记和ACK标记的报文时,能够间接进入到TIME_WAIT状态,而无须通过FIN_WAIT_2状态。(被动方)
- CLOSING(比拟少见): 这种状态比拟非凡,理论状况中应该是很少见,属于一种比拟常见的例外状态。失常状况下,当你发送FIN报文后,按理来说是应该先收到(或同时收到)对方的ACK报文,再收到对方的FIN报文。然而CLOSING状态示意你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什么状况下会呈现此种状况呢?其实细想一下,也不难得出结论:那就是如果单方简直在同时close一个SOCKET的话,那么就呈现了单方同时发送FIN报文的状况,也即会呈现CLOSING状态,示意单方都正在敞开SOCKET连贯。
- CLOSE_WAIT: 这种状态的含意其实是示意在期待敞开。怎么了解呢?当对方close一个SOCKET后发送FIN报文给本人,你零碎毫无疑问地会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正须要思考的事件是查看你是否还有数据发送给对方,如果没有的话,那么你也就能够close这个SOCKET,发送FIN报文给对方,也即敞开连贯。所以你在CLOSE_WAIT状态下,须要实现的事件是期待你去敞开连贯。(被动方)
- LAST_ACK: 这个状态还是比拟容易好了解的,它是被动敞开一方在发送FIN报文后,最初期待对方的ACK报文。当收到ACK报文后,也即能够进入到CLOSED可用状态了。(被动方)
- CLOSED: 示意连贯中断。
TCP的具体状态图可参考:
为什么建设连贯协定是三次握手,而敞开连贯却是四次握手呢?
这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连申请后,它能够把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但敞开连贯时,当收到对方的FIN报文告诉时,它仅仅示意对方没有数据发送给你了;但未必你所有的数据都全副发送给对方了,所以你可能不会马上敞开SOCKET,也即你可能还须要发送一些数据给对方之后,再发送FIN报文给对方来示意你批准当初能够敞开连贯了,所以它这里的ACK报文和FIN报文少数状况下都是离开发送的。
TCP的长处:
牢靠,稳固 。TCP的牢靠体现在TCP在传递数据之前,会有三次握手来建设连贯,而且在数据传递时,有确认、窗口、重传、拥塞管制机制,在数据传完后,还会断开连接用来节约系统资源。
TCP的毛病:
慢,效率低,占用系统资源高,易被攻打, TCP在传递数据之前,要先建连贯,这会耗费工夫,而且在数据传递时,确认机制、重传机制、拥塞管制机制等都会耗费大量的工夫,而且要在每台设施上保护所有的传输连贯,事实上,每个连贯都会占用零碎的CPU、内存等硬件资源。
IT入门 感激关注 | 练习地址:www.520mg.com/it