TCP三次握手那些事

临近5月,春招和实习招聘逐渐进入尾声。本文主要讨论面试中经常提问的TCP连接的机制,附带一些扩展知识。


 

参加面试的时候,过半的面试官都会问TCP相关问题,而最常见的问题就是:讲一下TCP三次握手(四次挥手)。

一般来说,TCP连接的过程是客户端发起,服务端确认请求,客户端再确认的三次握手过程。

具体三次如下:

1、客户端向服务器端发送SYN=1的TCP包,并附带初始序列号x。发送后,客户端的状态是SYN_SEND状态。

2、服务器端向客户端发送SYN=1,ACK=1的确认包,其序列号是服务器自己的序列号y,而确认序列号为x+1 。服务器端的状态是SYN_RCVD状态。

3、客户端再发送ACK=1的确认包,其序列号为x+1,确认序列号为y+1 。至此进入ESTABLISHED状态,TCP连接建立。

答到这里,面试官可能会问第二个问题:

能不能两次握手?

答案是不行。对于这个问题,RFC-793的原文是:

  The principle reason for the three-way handshake is to prevent old
  duplicate connection initiations from causing confusion.  To deal with
  this, a special control message, reset, has been devised.  If the
  receiving TCP is in a  non-synchronized state (i.e., SYN-SENT,
  SYN-RECEIVED), it returns to LISTEN on receiving an acceptable reset.
  If the TCP is in one of the synchronized states (ESTABLISHED,
  FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT), it
  aborts the connection and informs its user. 

我想大家都能理解。

很多时候,许多面经就到此为止了。但也经常会有一些扩展性问题,下面给出一些问题的解答:

1、TCP连接时,客户端不进行第三次握手会如何?

若不进行第三次握手,服务端将处在SYN_RCVD状态。若有很多(伪造的)客户端发起连接而不进行第三次握手,服务端不得不一一确认,并分配内存处理。

不仅如此,服务端要维护一个未连接队列,放置那些未完成的连接(半连接)。而大量伪造的连接将使半连接数达到最大值,使得正常连接被丢弃,最终导致网络瘫痪等问题。

这就是SYN洪泛,是一种拒绝服务攻击。

其实要识别这种攻击很简单,只要查看服务器上是否有大量的半连接即可。但这种攻击无法完全被阻止。

一种可行的方法是SYN Cookie,记录SYN连接的发起者,只有真正建立了连接,服务器才会为它分配内存。

还有其他方法例如过滤网关和增加最大半连接数。

2、TCP三次握手能否携带数据?

第三次握手是可以携带数据的。

3、TCP三次握手的开销过大?

T/TCP通过使用加速打开来避免三次握手:
1) 它为打开的连接指定一个32 bit的连接计数CC (Connection Count),无论主动打开还是
被动打开。一个主机的CC值从一个全局计数器中获得,该计数器每次被使用时加1。
2) 在两个使用T/TCP的主机之间的每一个报文段都包括一个新的TCP选项CC。这个选项
的长度为6个字节,包含发送方在该连接上的32bit的CC值。
3) 一个主机维持一个缓存,该缓存保留每个主机上一次的CC值,这些值从来自这个主机
的一个可接受的SYN报文段中获得。
4) 当在一个开始的SYN中收到一个CC选项的时候,接收方比较收到的值与为该发送方缓
存的CC值。如果接收到的CC比缓存的大,则该SYN是新的,报文段中的任何数据被
传递给接收应用进程(服务器)。这个连接被称为半同步。
如果接收的CC比缓存的小,或者接收主机上没有对应这个客户的缓存CC,则执行正常
的TCP三次握手过程。
5) 为响应一个开始的SYN,带有SYN和ACK的报文段在另一个被称为CCECHO的选项中
回显所接收到的CC值。
6) 在一个非SYN报文段中的CC值检测和拒绝来自同一个连接的前一个替身的任何重复的
报文段。
这种“加速打开”避免了使用三次握手的要求,除非客户或者服务器已经崩溃并重新启
动。这样做的代价是服务器必须记住从每个客户接收的最近的CC值。

4、TCP的初始序列号能否固定?

不建议,一是路由器会缓存数据包,导致序列号并非预期所设置;

二是如果序列号和四元组能够对应的话,那这个包就会被接受方确认。固定初始序列号容易被猜出,从而受到恶性攻击。

注:

本文主要引自《TCP/IP详解 卷一:协议》,部分内容源于网上。

如有侵权,请告知。

猜你喜欢

转载自www.cnblogs.com/sh1296/p/10777722.html
今日推荐