TCP为一定要三次握手吗?





TCP的三次握手是妇孺皆知的事情,似乎没有什么可以讨论的。笔者也曾经面试别人,提出过下面的问题:

“TCP为何要三次握手,四次断开?”

笔者期望的答案是:

TCP的连接建立一定要双向,所以第二个报文SYN/ACK齐发,而断开的时候可以保持半连接,即断开一半。理论依据是笔者根据Socket的实现得出的,Socket之中没有给出建立半连接的API,但是给出了shutdown可以关闭半连接。

事实真是如此吗?TCP不能直接建立半连接吗?看看文章。


TCP Portals: The Handshake’s a Lie!

文章作者对于三次握手提出了怀疑,参照标准并做了实验验证,符合老美做学问的思路。

文章引述了TCP RFC原文如下:

The synchronization requires each side to send its own initial
  sequence number and to receive a confirmation of it in acknowledgment
  from the other side.  Each side must also receive the other side's
  initial sequence number and send a confirming acknowledgment.

    1) A --> B  SYN my sequence number is X
    2) A <-- B  ACK your sequence number is X
    3) A <-- B  SYN my sequence number is Y
    4) A --> B  ACK your sequence number is Y

  Because steps 2 and 3 can be combined in a single message this is
  called the three-way (or three message) handshake.
看来握手也是可以三次可以四次。
作者同时写了code,并给出了PCAP供大家欣赏。从pcap来看作者是利用了syn的冲撞,
其实在linux协议栈中已经handle了作者的想法,
即在发出syn同时受到对方的syn的冲撞时刻,协议栈也是可以正确快速handle,且建立连接的。
这里作者其实并未真正的建立半连接。

尽管如此笔者仍得出一个结论,虽然打开半连接这种情况在实际中没有多大用途,但socket并未完全封装所有的TCP协议可能提供的接口。

(4个打分, 平均:5.00 / 5)

雁过留声

“TCP为一定要三次握手吗?”有13个回复

  1. 小老虎 于 2010-02-03 11:28 下午

    曾经我被面试过这个问题!悲剧

  2. BTC 于 2010-02-04 12:20 上午

    能三次握手就可以了,没理由要四次啊。

  3. 毛毛虫 于 2010-02-04 12:43 上午

    貌似有人曾经想数学证明3次是最合理的。

  4. dingding 于 2010-02-04 12:59 上午

    一个简洁的tcp流程, 5个报文就够
    # client server
    #———————
    #1 syn -》
    #2 《- synack
    #3 dat/fin -》
    #4 《- dat/fin
    #5 ack -》

    只能用中文符号了

  5. 小老虎 于 2010-02-04 1:47 上午

    to dingding:

    一边FIN了以后,另一边不需要ACK么?我记得卷一里说到要两边都ACK的啊,只是ACK和FIN有可能会在同一个包里传输,所以结束会话的时候可能是三次,也可能是四次的。

  6. droplet 于 2010-02-04 2:07 上午

    同时打开是可能的,不过要避免创建两个connection。
    3-way close是很常见的,没人规定一定要4-way close。
    半连接只能单向传数据,难道对TCP有这个需求?

  7. dingding 于 2010-02-04 2:14 上午

    to 小老虎

    tcp 协议规定, 除第1个syn外, 其他所以报文必须带ack, 故3/4报文没有写ack标识

  8. IE 于 2010-02-04 2:43 上午

    半链接业务还是挺常见的,有的金融业务就是这样的。单方关闭后,另一方还要交易一些数据后才关闭。

  9. Galaxy 于 2010-02-04 7:52 下午

    看了原文,大概就是SYN/ACK包可以反过来发。
    然后现在的防火墙是用SYN/ACK的方向来判断是出还是入的?
    所以,就可以翻小墙?

  10. lhz 于 2010-03-11 2:39 上午

    这个叫同时打开,在TCP/IP详解卷一中有过描述的,是标准行为。

  11. 巴卡 于 2010-03-11 2:54 上午

    四次也可以啊.sctp不就是四次吗?还可以避免dos.

  12. 老魏 于 2010-03-11 4:00 上午

    你还好么?我这里还可以
    我知道你,我这里也不错。
    哦,我现在也知道你还好了。。。
    两边都OK。

  13. appleleaf 于 2010-03-11 5:04 上午

    这个是应该叫“同时打开”,只不过我忘了怎么描述了。

发表评论