细说TCP连接中的三次握手和四次挥手
三次握手和四次挥手可能是面试的时候经常会被问到的一个问题
今天就给大家详细的说一说,首先给大家科普几个概念性的东西
LISTEN:等待从任何远端TCP 和端口的连接请求。
SYN_SENT:发送完一个连接请求后等待一个匹配的连接请求。
SYN_RECEIVED:发送连接请求并且接收到匹配的连接请求以后等待连接请求确认。
ESTABLISHED:表示一个打开的连接,接收到的数据可以被投递给用户。连接的数据传输阶段的正常状态。
FIN_WAIT_1:等待远端TCP 的连接终止请求,或者等待之前发送的连接终止请求的确认。
FIN_WAIT_2:等待远端TCP 的连接终止请求。
CLOSE_WAIT:等待本地用户的连接终止请求。
CLOSING:等待远端TCP 的连接终止请求确认。
LAST_ACK:等待先前发送给远端TCP 的连接终止请求的确认(包括它字节的连接终止请求的确认)
TIME_WAIT:等待足够的时间过去以确保远端TCP 接收到它的连接终止请求的确认。
TIME_WAIT 两个存在的理由:
1.可靠的实现tcp全双工连接的终止;
2.允许老的重复分节在网络中消逝。
CLOSED:不在连接状态(这是为方便描述假想的状态,实际不存在)
七层网络协议
应用层: 与其它计算机进行通讯的一个应用,它是对应应用程序的通信服务的
表示层: 这一层的主要功能是定义数据格式及加密。
会话层: 它定义了如何开始、控制和结束一个会话,包括对多个双向消息的控制和管理,以便在只完成连续消息的一部分时可以通知应用,从而使表示层看到的数据是连续的,在某些情况下,如果表示层收到了所有的数据,则用数据代表表示层
传输层: 这层的功能包括是否选择差错恢复协议还是无差错恢复协议,及在同一主机上对不同应用的数据流的输入进行复用,还包括对收到的顺序不对的数据包的重新排序功能。例如 TCP,UDP
网络层:这层对端到端的包传输进行定义,它定义了能够标识所有结点的逻辑地址,还定义了路由实现的方式和学习的方式。为了适应最大传输单元长度小于包长度的传输介质,网络层还定义了如何将一个包分解成更小的包的分段方法 例如:IP
数据链路层:它定义了在单个链路上如何传输数据。这些协议与被讨论的各种介质有关。
物理层:OSI的物理层规范是有关传输介质的特性,这些规范通常也参考了其他组织制定的标准。
SYN
:同步序列编号(Synchronize Sequence Numbers)。是TCP/IP
建立连接时使用的握手信号
ACK
:即是确认字符,在数据通信中,接收站发给发送站的一种传输类[控制字符]。表示发来的数据已确认接收无误
需要搞清楚的问题
为什么连接的时候是三次握手?
什么是半连接队列?
ISN(Initial Sequence Number)是固定的吗?
三次握手过程中可以携带数据吗?
如果第三次握手丢失了,客户端服务端会如何处理?
SYN攻击是什么?
挥手为什么需要四次?
三次握手
1.1 三次握手
三次握手(Three-way Handshake)其实就是指建立一个TCP连接时需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备
刚开始客户端处于 Closed 的状态,服务端处于 Listen 状态
第一次握手:客户端给服务端发一个 SYN 报文,并指明客户端的初始化序列号 ISN。
这个时候不能携带数据(我可以发送?你能收到吗)
第二次握手:服务器收到客户端的 SYN 报文之后,会返回一个新 SYN 报文作为应答,
并指定自己的初始序列号,将这个初始序列号 +1 作为 ACK 的值发送给服务器,
表示自己已经收到了客户端的 SYN 报文(我能收到,你能收到吗)
第三次握手:同样客户端收到 SYN 报文之后, 会继续发送一个 SYN 报文
并将 ACK+1 作为一个新的 ACK值表示收到了服务端的 SYN 报文,
服务器收到 ACK 报文之后打开端口建立连接(我收到了,建立连接吧)
1.2 为什么需要三次握手,两次不行吗?
第一次握手:客户端发送网络包,服务端收到了。
我可以发送?你能收到吗
第二次握手:服务端发包,客户端收到了。
我能收到,你能收到吗
第三次握手:客户端发包,服务端收到了。
我收到了,建立连接吧
因此,需要三次握手才能确认双方的接收与发送能力是否正常。
1.3 什么是半连接队列?
服务器第一次收到客户端的 SYN 之后,此时双方还没有完全建立其连接,服务器会把此种状态下
请求连接放在一个队列里,我们把这种队列称之为半连接队列。 通俗来说服务器收到了客户端的SYN请求
这个时候我们之间想建立连接,但是还没有连接成功这种状态我叫它为半连接状态,所以放到半连接队列
1.4 ISN(Initial Sequence Number)是固定的吗?
当一端为建立连接而发送它的SYN时,ISN随时间而变化,因此每个连接都将具有不同的ISN。
ISN可以看作是一个32比特的计数器,每4ms加1,这样选择序号的目的在于防止在网络中被延
迟的分组在以后又被传送,而导致某个连接的一方对它做错误的解释
三次握手的其中一个重要功能是客户端和服务端交换 ISN(Initial Sequence Number),
以便让对方知道接下来接收数据的时候如何按序列号组装数据。如果 ISN 是固定的,
攻击者很容易猜出后续的确认号,因此 ISN 是动态生成的。
1.5 三次握手过程中可以携带数据吗?
其实第三次握手的时候,是可以携带数据的。但是,第一次、第二次握手不可以携带数据
因为 第一次握手中的 SYN 报文中放入大量的数据。会加大服务器的压力,如果遇见恶意攻击的人
他每次都在第一次握手中的 SYN 报文中放入大量的数据,然后疯狂着重复发 SYN 报文的话,这会
让服务器花费很多时间、内存空间来接收这些报文。
第三次握手的时候我可以接受到服务器返回的ACK确认值就表示我们之间的服务器的接收、
发送能力是正常的这个时候就可以进行连接了,自然也就可以携带数据
四次挥手
2.1 四次挥手
建立一个连接需要三次握手,而终止一个连接要经过四次挥手(也有将四次挥手叫做四次握手的)。这由TCP的半关闭(half-close)造成的。所谓的半关闭,其实就是TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。
TCP 连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),客户端或服务端均可主动发起挥手动作。
四次挥手的过程如下:
第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。
第二次挥手:服务端收到 FIN 之后,把客户端的序列号值 +1 作为 ACK 报文的序列号值,
表明已经收到客户端的报文了,此时的TCP处于半关闭状态,客户端到服务端的连接释放。
(确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号)
第三次挥手 服务端也想断开连接了,服务器关闭客户端的连接,发送一个FIN给客户端。
第四次挥手 客户端发回ACK报文确认,并将确认序号设置为收到序号加1。
2.1 挥手为什么需要四次?
因为需要保证所有的报文都被接受,比如我们说话,你关门吧,我回家了,我可以听见后面的话我回家了,
但是程序不一样,你关门吧,我回家了,他听到你说你关门把就把门关上了,你收不到后面的消息了,就
很尴尬,所以需要分开发送