本文共 1569 字,大约阅读时间需要 5 分钟。
本节书摘来自异步社区《Wireshark网络分析的艺术》一书中的被误解的TCP,作者林沛满,更多章节内容可以访问云栖社区“异步社区”公众号查看。
被误解的TCP
Wireshark网络分析的艺术人一旦形成某种思维定势,就很难再改变了。知道我收到最多的读者来信是问什么吗?“林工,有些TCP包发出去之后没有看到对应的Ack,算不算丢包啊?”这个问题让我很是好奇,明明RFC上没有这样的规定,为什么总有读者觉得每一个数据包都应该有对应的Ack呢?后来才注意到,很多提问者是做网站开发出身的,已经习惯了每个HTTP请求发出去,就一定会收到一个HTTP响应(见图1),因此就把这个模式套到了TCP上。其实不止HTTP,绝大多数应用层协议都采用这种一问一答的工作方式。也许以后会有手机厂商优化它,然后以此作为卖点。如果是从我这本书里学到的,请为它命名“林朗台算法”。
既然接收方不一定收到每个包都要Ack,那发送方怎么知道哪些包虽然没有相应的Ack,但其实已经送达了呢?记住,Ack是有累积效应的,它隐含了“在此之前的其他包也已收到”的意思,比如图3中第97号包的Ack=65701不仅表示收到了96号包(其Seq+Len=64273+1428=65701),而且暗示之前的其他包也都收到了。因此86~95号包虽然没有被显式Ack,但发送方知道它们也已经被送达了。
另一个对TCP的广泛误解则和UDP相关。有不少技术人员认为TCP的效率低,因为其传输过程中需要往返时间来确认(Ack)。而UDP无需确认,因此能不停地发包,效率就高了。事实真的如此吗?这其实是对TCP传输机制的严重误解。我们可以假设一个场景来类比TCP的工作方式:有大批货物要从A地运往B地。如果只用一辆货车来运的话,马路上就只有一辆车在来回跑(回程相当于TCP的Ack包),效率确实很低,对TCP的误解可能也出自这个原因。但如果在不塞车的前提下尽量增加货车数量,使整条马路上充满车,总传输效率就提高了。TCP发送窗口的意义相当于货车的数量,只要窗口足够大,TCP也可以不受往返时间的约束而源源不断地传数据。这就是为什么无论在局域网还是广域网,TCP还是最受欢迎的传输层协议。
当然TCP确实也有因为往返时间而降低效率的时候,比如在传输小块数据的场景。本来能在1个往返时间完成的小事,却要额外耗费3次握手和4次挥手的开销,DNS查询就符合这种场景。目前HTTP基本建立在TCP连接上,所以也会因为TCP的三次握手而增加延迟。你可能听说过Google发布的QUIC(Quick UDP Internet Connection)协议,它就是为了消除TCP的延迟而设计的代替品。在某些领域可以视为TCP的竞争对手,目前在Google的网站上已经可以试用了。
本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。