共计 3132 个字符,预计需要花费 8 分钟才能阅读完成。
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