腾讯实习面试:tcp是不是一定要3次握手?

哈喽,大家好,我是明智

在前面的几篇文章给大家分析了面试中常见的几个问题:

《美团一面,发生OOM了,程序还能继续运行吗?》

《美团一面:碰到过OOM吗?你是怎么处理的?》

《美团一面,你碰到过CPU 100%的情况吗?你是怎么处理的?》

咱们在面试中除了经常被问到CPU跟内存的问题外,还有一个重要的考点就是网络。

正好前段时间有个小伙伴在腾讯面试的时候被问到了这个问题:tcp是不是一定要3次握手?我也借着这个问题跟大家聊一聊tcp的三次握手

这篇文章咱们分为三部分

  1. tcp的三次握手流程是什么样的?

  2. tcp为什么是3次握手?

  3. tcp一定要经过三次握手才能发送数据吗?

TCP三次握手的流程

TCP 三次握手(Three-way Handshake)是保证客户端和服务器之间可靠通信的一种机制。具体流程如下:

  1. 第一次握手(SYN):客户端发送一个 SYN(synchronize)报文给服务器,表示请求建立连接。这个报文里有一个初始序列号(Initial Sequence Number,ISN)。

  2. 第二次握手(SYN-ACK):服务器收到 SYN 报文后,响应一个 SYN-ACK 报文,表示同意建立连接,并且它也会发送自己的初始序列号。

  3. 第三次握手(ACK):客户端收到 SYN-ACK 报文后,发送一个 ACK(acknowledgment)报文给服务器,至此,连接正式建立。

outside_default.png

了解三次握手的具体流程,是我们进行下面讨论的基础

TCP为什么是三次握手?

这个问题嘛,看似简单,实际上也不复杂

c5d9882b684a7ae7a1a77c56895020f5.jpeg

首先,咱们得明白TCP的设计初衷是要确保通信的可靠性和稳定性,是为了建立一个可靠的连接,而三次握手就是为了达到这个目的。

一个连接怎样才是可靠的呢?

简单来说:通信双方都要确认对方能正常接收到自己的消息

对于客户端来说需要通过两次握手来确认服务能收到自己的消息

第一次握手:客户端发送SYN包,相当于询问服务端:“你能听到我说话吗?”

第二次握手:服务端发送ACK包,相当于回应服务端:“我可以听到你说话”

同理,服务端也需要两次握手来确认客户端能接受到自己的消息

第一次握手:服务端发送SYN包,相当于询问客户端:“你能听到我说话吗?”

第二次握手:客户端发送ACK包,相当于回应服务端:“我可以听到你说话”

有的小伙伴可能就会有疑问,这样算起来tcp岂不是要四次握手了吗?但是咱们可以发现,第二次握手跟第三次握手都是服务端发送数据,因此这两次握手可以合并为一次,咱们回顾之前tcp三次握手的流程也可以发现,在第二次握手中,服务端发送的数据包是SYN+ACK

outside_default.png

TCP一定要经过三次握手才能发送数据吗?

这个问题是面试中的一个“坑”。答案是:不一定

根据RFC 793(TCP的权威文档),在三次握手的过程中,第三次握手是可以携带数据的。在RFC 793文档中,明确指出了:

After sending the initial SYN segment, the client can start sending data as soon as it receives the SYN-ACK from the server. The third handshake (ACK) can carry data in it.

翻译过来就是:客户端在发送完初始的SYN报文后,一旦收到服务器的SYN-ACK报文,就可以开始发送数据。第三次握手(ACK)也可以携带数据。

这意味着,理论上,数据传输并不一定非要等到三次握手完全结束后才开始。在第二次握手结束后(也就是客户端收到服务器的SYN-ACK),客户端就已经可以开始传输数据了。第三次握手时,ACK报文可以包含数据,从而提高了连接建立的效率。

当然,上面只是理论!

在实际应用中,绝大多数TCP库会遵循TCP的标准流程,即在第三次握手完成后才开始正式传输数据。这是因为TCP协议的设计初衷就是为了保证连接的可靠性和稳定性,按照标准的三次握手流程进行,可以确保双方都准备好了才开始数据传输,从而提高通信的可靠性

例如在java的类库中:

public class BioClient {
    public static void main(String[] args) throws Exception {
        Socket client = new Socket();
        client.connect(new InetSocketAddress("your host",8080));
        // send request
        // ..
    }
}

如果你使用上面的代码并进行抓包分析,你会发现只有当第三次握手结束后connect才会解阻塞,只有解阻塞后你才能开始向服务端发送请求。

所以,这个问题咱们只讲理论的话,答案是可以的,但是实际上基本上所有的库都会遵循TCP的标准流程,在三次握手。

作者简介

  1. 大三退学,创业、求职、自考,一路升级

  2. 7年it从业经验,多个开源社区contributor

  3. 专注分享成长路上的所悟所得

  4. 长期探索 个人成长职业发展副业探索

推荐阅读

美团一面,你碰到过CPU 100%的情况吗?你是怎么处理的?

美团一面:碰到过OOM吗?你是怎么处理的?

美团一面,发生OOM了,程序还能继续运行吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值