网络基础-tcp/ip的三次握手和四次挥手

这道题目已经很多次在笔试中被问及了,所以,打算巩固一下,写成一篇完善的文章,参考了以下的两篇文章

https://baijiahao.baidu.com/s?id=1618114723935605183&wfr=spider&for=pc
https://blog.csdn.net/qq_35860138/article/details/82054793
https://blog.csdn.net/qq_38950316/article/details/81087809

相关名词介绍

  1. syn:同步序列编号(Synchronize Sequence Numbers)。是TCP/IP建立连接时使用的握手信号。在客户机和服务器之间建立正常的TCP网络连接时,客户机首先发出一个SYN消息,服务器使用SYN+ACK应答表示接收到了这个消息,最后客户机再以ACK消息响应。这样在客户机和服务器之间才能建立起可靠的TCP连接,数据才可以在客户机和服务器之间传递。(详细可以看这个博客:https://blog.csdn.net/zzz_781111/article/details/4183743)
  2. ack:ACK (Acknowledge character)即是确认字符,在数据通信中,接收站发给发送站的一种传输类控制字符。表示发来的数据已确认接收无误
  3. SYN_SENT:表示请求连接。
  4. SYN_RECV:是指,服务端被动打开后,接收到了客户端的SYN并且发送了ACK时的状态。再进一步接收到客户端的ACK就进入ESTABLISHED状态。
  5. LISTENING:提供某种服务,侦听远方TCP端口的连接请求,当提供的服务没有被连接时,处于LISTENING状态,端口是开放的,等待被连接。
  6. ESTABLISHED:ESTABLISHED状态是表示两台机器正在传输数据。
  7. FIN-WAIT-1:等待远程TCP连接中断请求,或先前的连接中断请求的确认,主动关闭端应用程序调用close,TCP发出FIN请求主动关闭连接,之后进入FIN_WAIT1状态。
  8. CLOSE-WAIT:等待从本地用户发来的连接中断请求 ,被动关闭端TCP接到FIN后,就发出ACK以回应FIN请求(它的接收也作为文件结束符传递给上层应用程序),并进入CLOSE_WAIT。
  9. TIME-WAIT:在主动关闭端接收到FIN后,TCP就发送ACK包,并进入TIME-WAIT状态,等待足够的时间以确保远程TCP接收到连接中断请求的确认,很大程度上保证了双方都可以正常结束,但是也存在问题,须等待2MSL时间的过去才能进行下一次连接。

建立连接时的三次握手

首先,我们分为客户端和服务器端,
第一次握手:客户端先向服务器端发送一个syn包来请求连接,然后客户端进入syn_sent状态,等待服务器确认。
第二次握手:服务器端收到syn包,为了确认客户的syn,同时自己也需要发送syn包,所以服务器端向客户端发送一个ack+syn包来确认连接,服务器端进入syn_rcvd状态
第三次握手:客户端接受到信号后,发送ack到服务器端确认连接,至此,连接新建成功。

举个例子:有一个朋友在路上遇到你,向你打招呼(这时候就相当于你朋友是客户端,你是服务器端,打招呼就相当于发送了一个syn包),这时候你怕会错意,所以就对你朋友微笑点头一下(就相当于服务器端向客户端发送ack和syn包确认连接),最后你朋友看到你的微笑和点头开心也微笑地点头(也就是发送了一个ack包),最后你们相遇了(进入establish状态)。

在这里插入图片描述

tcp的数据传输(例子默认客户端为发送端)

数据传输过程中,有四个机制需要大家了解,分别是:

  1. 超时重传:这个一个用来保证TCP传输的可靠性,客户端每次发送数据包,发送的数据报都有seq号,(服务器端收到数据后,会回复ack进行确认,表示某一个seq号的数据已经收到),如果客户端等待了一端时间,还没有收到服务器端的ack包,则认为是数据包丢失,便重新打招呼

举例就是等你遇到人挥手打招呼,等了三秒,对方没有回应,你便再次挥手打招呼一样

  1. 快速重传: 服务器端发现数据包丢失了,就会认为报文丢失,便发送ack报文告诉客户端重传失去的报文。如果客户端连接收到标号相同的ack包,就会触发快速重传。(超时是等待,快速是接受到大量相同的ack报文,触发重传的条件不同)

举例就是你教朋友编写一段代码,然后朋友有一段没听清,一直给出疑惑的表情(相当于标号相同的ack包),这时候你明白了他没有听到,便重新跟他讲解一次

  1. 流量控制:主要说的是TCP滑动窗流量控制,TCP头有一个字段叫window,又叫Advertised-Window,这个字段是接受端告诉发送端,还有多少缓冲区可以接受数据,于是发送端就可以根据缓冲区来控制发送数据的多少,是提高TCP传输效率的一种机制

相当于在教室里,你告诉老师在上课这段时间,我最多可以听懂多少道题的讲解,让老师有个把握来决定教你多少道题。

  1. 拥塞控制:基于整个网络考虑的状态,(假设网络延迟,重传会导致更大的延迟和更多的丢包,所以需要拥塞控制),拥塞控制策略:慢启动,拥塞避免,拥塞发送,快速恢复
    在这里插入图片描述

四次挥手段断开连接

第一次挥手:主动关闭方发送一个fin,用来关闭主动发到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方,我不会再发送数据给你了。

第二次挥手:被动关闭方收到fin包后,发送一个ack给对方。

扫描二维码关注公众号,回复: 9971967 查看本文章

第三次挥手:被动关闭方发送一个fin,用来关闭被动关闭端到主动关闭端的数据传输,也就是告诉主动关闭方,我的数据也发送完了,不会再发数据给你了。

第四次挥手:主动关闭端收到fin后,也发送一个ack给被动关闭端,至此,完成四次挥手

在这里插入图片描述

在这里插入图片描述

重点:其实跟三次握手很像,只是服务器端,发送ack和fin包的过程是分开的。(四次挥手也并不总是四次挥手,中间的两个动作有时候是可以合并一起进行的,这个时候就成了三次挥手,主动关闭方就会从fin_wait_1状态直接进入到time_wait状态,跳过了fin_wait_2状态。)

在server发送了fin后,client还有一个time_wait状态,他是主动关闭方在回复完对手的挥手后进入的一个长期状态,一般持续4分钟。
time_wait的作用:
1.重传最后一个ack报文,如果被动关闭端没有收到最后一个ack的话,被动关闭方将为重复发送fin片段,所以主动关闭端为了确保对方可以收到ack,不能在传完最后的ack后就关闭,而是应该进入time_wait,确保在再次接收到fin可以向被动关闭端重发ack报文
2. 同时在这段时间内,该链接在对话期间于网际路由上产生的残留报文(因为路径过于崎岖,数据报文走的时间太长,重传的报文都收到了,原始报文还在路上)传过来时,都会被立即丢弃掉。4分钟的时间足以使得这些残留报文彻底消逝。不然当新的端口被重复利用时,这些残留报文可能会干扰新的链接。

为什么三次握手

参考文章(很详细):https://blog.csdn.net/lengxiao1993/article/details/82771768

为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤
如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认

为什么四次挥手

因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手

如果已经建立了连接,但是客户端突然出现故障了怎么办?

TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

发布了36 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/s_xchenzejian/article/details/102514909