TCP协议

目录

二、三次握手建立连接

三、四次挥手释放连接

常见面试题:

问题1:为什么要三次握手,二次握手行不行?

问题2:为什么建立连接的时候需要三次握手,而释放连接却需要四次挥手?

问题3:如果在建立连接后,客户端突然出现故障了怎么办?

问题4:什么是SYN洪泛攻击?


一、TCP是什么

传输控制协议(TCP,Transmission Control Protocol)是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议。

二、三次握手建立连接

三次握手通俗可以形容成对话,如下:

 

TCP协议

男的相当于客户端,女的相当于服务器。当客户端发起连接时,会先发送一个连接请求,当服务端答应(确认)后,客户端再发送一个知道可以说话了的信息给服务端,然后客户端才真正开始说话。

详细的过程如下:

1.一开始,服务器会有个线程时刻监听(listen)是否有客户端的连接请求。

2.客户端主动发送一个连接请求报文段,为了标识这是个连接请求,会把SYN=1,seq=x (seg为报文序号,x是随机产生的)。这个报文段无应用层数据。

3.服务器收到这个请求后,会建立接收缓存区,且回复一个确认连接报文,这个报文同样也会把SYN=1,但是会多了一个确认为ACK,ACK表示收到了前一个报文,并且也会有与ACK成对出现的ack,ack表示渴望收到的下一个报文的报文序号,由于前一个报文序号为x,所以渴望收到的下一个报文序号当然就是x+1了,因此ack=x+1。同样的,这里服务端也会随机出自己的报文号 y 发给客户端。

4。客户端回复一个确认报文段,告知服务器,自己已经知道服务器收到自己的连接请求了。对于客户端而言,发送出去这个报文后,就可以开始建立连接了。而服务器收到这个报文后,才开始建立连接。(SYN只有两个情况会为1,就是连接请求报文和确认收到连接请求报文)

TCP协议

三、四次挥手释放连接

四次挥手通俗可以形容成对话,如下:

TCP协议

当客户端发送完全部数据后,就会告诉服务器自己已经没数据发送了。但是由于TCP是全双工的,即客户端可以给服务器发数据,服务器也可以给客户端发数据,所以虽然客户端自己发送完了,但是还得要等服务器也发送完才能关闭连接。当服务器发送完后,服务器就会告诉客户端自己也没数据可发了,然后客户端收到服务器已发送完数据的消息后,便回了一个确认消息,告诉服务器,客户端已经知道了,服务器可以关闭连接了。

详细如下图:

TCP协议

过程:

1. 客户端发送完所有数据后,向服务器发送一个请求释放连接的报文。此报文FIN为1,这个报文的序号seg=u(这次的u不是随机的,而是等于前面已经传送过来的数据的最后一个字节的序号加1)。

2. 客户端发送完请求释放连接的报文后,就开始等了,分两个阶段等,第一个是 FIN-WAIT-1 ,是等待服务器确认收到客户端发的释放连接的确认报文。

3. 客户端收到服务器发送的确认报文后,就开始等服务器发送完它自己的数据了,这就是第二个阶段的等---FIN-WAIT-2。

4.当服务器把所有数据都发送完毕后,就向客户端发送连接释放报文,只要是连接释放报文,都有FIN=1的。

5.客户端收到后,必须发出确认报文,告诉服务器自己已经知道了,不再等了。

6.服务器收到这个确认报文后,就开始释放连接。

7. 当客户端则会进入 TIME-WAIT,这个等待是怕 自己发送的确认报文在网络中丢失了,如果确认报文丢失了的话,服务器得不到应答,就会重发一次连接释放报文,这时候处于TIME-WAIT的客户端就能够收到,要是客户端没有TIME-WAIT,马上释放连接的话,那么如果确认报文丢失了,客户端就不知道了,这时候服务器会一直重发连接释放报文而不得关闭。

 

常见面试题:

问题1:为什么要三次握手,二次握手行不行?

不行,首先我们来看看第三次握手存在的意义:为了防止已失效的连接报文突然又到了服务器,造成双方的不一致,导致资源兰浪费

举个例子,如果只有二次握手的话:

1.客户端向服务器发送一个SYN连接请求报文,但是由于网络原因,此报文在传送途中滞留了很长时间。

2.客户端等了很久没等到来自服务器的确认报文,于是客户端以为自己发的SYN连接报文丢包了(其实没有丢),于是重新发送一个SYN连接报文。

3.这一次服务器收到了,回复了确认报文,双方建立连接。

4.这时候,滞留的SYN报文达到了服务器,如果这个SYN在连接过程中到达,那就没事,因为服务器会自动忽略它。但如果是在释放了连接(即客户端和服务端通信结束后)到达服务器,那么服务器会以为又有客户端想跟它建立连接。

5.那么服务器就会回复一个连接确认报文,因此是二次握手,所以服务器开始建立连接。

6.当客户端收到了这个连接确认报文后,由于客户端此时是没有发起连接请求的,因此客户端会忽略它。

7.这时候,服务器以为连接好了会一直给客户端发送数据,但由于客户端是没处理连接状态的,所以会丢弃服务器发来的数据。

8.过了一会,客户端想向服务器建立连接,发送了新的SYN连接请求报文,但服务器认为已经在连接中了,就不理睬这个新的SYN报文了。就会出现大家都尬在这。服务器发数据,客户端丢弃,客户端想发,服务器又丢弃连接请求。

其实这些问题也不是不能解决的,当客户端老发现服务器给自己发信息,且自己老是丢弃,则可能会向服务器发送一个RST(即报文中RST位置为1),强制服务器关闭连接。但资源已经被浪费掉了,而三次握手就不会出现这种问题。

问题2:为什么建立连接的时候需要三次握手,而释放连接却需要四次挥手?

先分开来看:

1. 三次握手时:当服务器收到客户端是SYN连接请求时,发送的确认报文中,不仅仅也有ACK确认信息,还有SYN同步信息。所以这是一起发的所以三次握手会比四次挥手少了一次,但为什么在挥手时,不能像握手时这样搞呢?

2. 四次挥手时:服务器收到客户端来的FIN释放连接请求时,服务器不能同时发送ACK和FIN,因为这时候只是客户端发送完数据,但服务器还有数据要发送,所以这时候服务器只能发送 ACK确认已经收到来自客户端的FIN,而要等到服务器发送完全部数据后,服务器才能发送FIN报文。因此,挥手时比握手多出一次的根本原因是,客户端想要释放连接时,服务器还有数据没发完

问题3:如果在建立连接后,客户端突然出现故障了怎么办?

TCP是有一个保活计时器的,因为如果客户端出故障了,服务器也不能一直等下去,白白耗费资源。服务器每次收到客户端的消息后,都会重新复位这个计时器,时间通常是2小时。若两小时内都没有收到服务器的数据,服务器会发送一个探测报文,以后每隔75秒发送一次,当连续发送10个报文都没有回应时,服务器就认为客户端出了故障,接着就关闭连接。

问题4:什么是SYN洪泛攻击?

由于连接的建立需要三次握手,当攻击方(客户端)给服务器发送一个SYN连接建立报文后,服务器会回复一个ACK确认报文,但攻击方收到服务器的报文后,不给它回复一个再确认的报文,这样子服务器就会以为是自己的确认报文丢失了,然后就会不断重发。这时候,攻击方向服务器发送多个SYN连接请求,但是每个都不建立三次握手,因此在服务器上,这些TCP连接都会消耗CPU和内存,最后服务器死机,无法为正常用户提供服务。