前言
TCP和UDP是今天应用传输最多的协议,拥有最核心的垄断地位,今天互联网的传输层几乎都是基于这两个协议打造的。无论是应用开发框架、设计选型、做底层的优化、还是定位线上问题,只要碰到网络肯定逃不开TCP协议的相关知识,在面试当中,TCP协议一直是一个高频的考察内容,外加TCP的关联知识比较多,因此面试也是五花八门。在介绍今天的主题之前,我先提一道高频面试题:TCP为什么握手是3次、挥手是4次?
TCP协议
TCP Transmission Control Protocol ,是一个传输层协议,提供Host-Host数据的可靠传输,支持全双工,是一个连接导向的协议。
这里面涉及到很多的概念,例如,Host to Host 主机到主机、连接、会话、双工/单工及可靠性等。
主机到主机(Host To Host)
提供的是Host To Host 传输,一台主机通过TCP发送数据给另一个主机。这里的主机Host实际上是一个抽象的概念,实际上是手机、平板、电脑等等都是Host,收发数据的其实都是主机Host,所以双方是平等的。
网络通信五层协议.png
TCP协议网上我们称之为应用到应用(Application To Application)的协议。为什么是应用到应用的协议呢?比如说你微信发消息给张三了,你的微信客户端,微信的聊天服务,其实他们都是应用,微信有自己的聊天协议,微信的聊天协议是应用到应用的协议。如果微信的聊天协议想要工作,那么就需要一个主机到主机的协议,帮助他实现通信,而TCP的上层有太多的应用,不仅仅有微信,还有元神啊,抖音啊,网易云音乐。因此TCP上层的应用层协议使用TCP的能力的时候,需要告知TCP是哪一个应用,这个就是端口号的设计,端口号用来区分应用,后面我们还会讨论。
TCP要实现主机到主机的通讯,就需要知道主机们的网络地址,也就是IP地址,但是TCP又不负责地址到地址(Address To Address)的传输,因此TCP协议是把IP地址去交给互联网层去处理。
互联网层也叫做网络层,提供的是地址到地址的通讯IP协议就是再这一层工作的。互联网层解决的是地址到地址的通讯,但是他不负责信号在两个设备之间的传递。因此互联网层又会调用下方的链路层在两个设备之间传递信息。当信号再两个设备间传递的时候,科学家又设计了一个物理层去封装最底层的物理设备,传输介质的由最下层的物理层提供最底层的传输能力。以上的传输架构我们称之为互联网协议群(TCP/IP协议群)。
总结一下:主机到主机(Host To Host)是为应用提供应用间通信的能力。
什么是连接和会话?
连接(Connection)是通讯双方的一个约定,目标是两个在通信的程序之间产生一个默契,包保证两个程序都在线,并且尽快的响应对方的请求,这个就是连接。
连接,一种传输数据的行为,传输之前,建立一个连接。数据收发双方的内存中都建立一个用于维护数据传输状态的对象,比如说双方的IP 和端口是多少?现在已经发送了多少数据?状态健康吗?传输速度如何?。所以,连接是网络行为状态的记录。
和连接关联的一个名称,叫做会话(Seesion)。会话是应用的行为,比如说张三和你聊天,张三是一个会话,当你开始打字,开始传输数据,你和微信服务器之间是建立的一个连接。如果你们聊一段时间,各自休息了,约定不要关闭微信,一个小时后再聊,那么你们连接是断开了,但是会话没有断开。因为聊天窗口没有关,所以会话还在。
有些系统当中,会话会自动重连(也就是重新创建连接),或者帮助创建连接。此外,会话也负责在多次连接中保存状态,比如HTTP Session在多次HTTP请求(连接)间保持状态。
总结一下:会话是应用层的概念,连接是传输层的概念。
双工/单工
双工/单工.png在任何一个时刻,如果数据只能单项发送,就是单工。单工需要至少一条线路。
如果在某个时刻数据可以向一个方向传输,也可以向另一个方向反向传输,而且交替进行,我们称之为半双工,半双工也至少需要一条线路。
如果任何时刻数据都可以双向发送,就是全双工,全双工需要大于一条线路。
TCP是一个双工协议,数据任何时候可以双向传输,这就意味客户端和服务端是平等的在发送和接受信息。正因为如此,客户端和服务端在TCP协议中有一个平等的名称Host(主机)
什么是可靠性?
上文提到的TCP提供的是可靠性,那么可靠性是什么呢?可靠性是指数据保证无损传输。
如果发送方按照顺序发送,然后数据无序的在网络间传递,就必须有一种算法在接收方将数据恢复到原有的顺序。另外,如果发送方同时要把消息发送给多个接收方,这种情况称之为多播。可靠性要求每个接收方都无损的接收到相同的副本,多播情况还有强可靠性,就是一个消息,到达任何一个接收者,那么所有的接受者都必须收到这个消息,本专栏中,我们都是基于单播去讨论可靠性。
TCP的握手和挥手
TCP是一个连接导向的协议,设计有建立连接(握手)和断开连接(挥手)的过程。TCP没有涉及会话,因为会话通常是一个应用的行为。
TCP协议通常有这样的几个基本操作。
- 如果一个Host向另一个Host发起连接,我们称之为SYN(Synchronization),请求同步。
- 如果一个Host向另一个Host主动断开连接,称为FIN(Finish),表示请求完成。
- 如果一个Host给另一个Host发送数据,我们称为PSH(Push),数据推送。
以上三种情况,接收方收到数据之后,都需要给接收方发送一个ACK响应,请求响应模型是一个可靠性的要求。如果一个没有响应,发送方可能会认为自己需要重发这个请求。保持连接和可靠性约束,TCP要保证每一条发出的数据必须要给返回,返回的数据叫做ACK,也就是响应。按照这个思路,你可以看看建立连接是不是需要三次握手。
建立连接过程(三次握手)
三次握手过程.png首先客户端要发送消息给服务端SYN,发一次同步请求。服务端准备之后就需要进行连接。服务端针对客户端的响应,需要给一个ACK,你可能会问,到这里不就可以了吗?两次握手就够了,但其实并不是,因为服务端还没有确定客户端是否准备好了。如果现在直接发送数据,客户端可能还没准备好去接受数据。因此还需要增加一个过程,服务端要向客户端发送一个SYN给客户端,客户端准备就绪之后,再给服务端一个ACK。你可能会问,这不是经过了六次吗,怎么是三次握手?实际上客户端给服务端的SYN是第一次握手,服务端准备不是数据传输,所以不算握手。服务端对客户端的ACK跟服务端给客户端发送的SYN是同时发生的,可以作为一条数据SYNACK传递给客户端,因此算一次握手。客户端的准备没有传输数据,也不算握手。客户端给服务端的ACK是第三次握手。
断开连接(四次挥手)
客户端发一个FIN到服务端,服务端接收到请求之后,马上给一个ACK。这里需要思考一个问题,可不可以马上回传一个FIN给客户端?不行,因为断开连接需要处理的事情比较多,比如说客户端已经发出,但是服务端还没有ACK的消息,或者服务端还有自己的资源没有释放,所以这里不能像握手那样操作,所以服务端会经过一段时间的等待,确定可以关闭了,再发一个FIN给到客户端,客户端接受到服务端的FIN,客户端可能有自己的资源需要释放,客户端处理完成之后会发送一个ACK。所以刚好是四次挥手。
总结
1.TCP提供了连接(Connection),让双方的传输更加稳定、安全。
2.TCP没有直接提供会话,因为应用对会话的需求多种多样,比如聊天的会话可能需要保持双方的聊天记录,电商程序会话需要保持购物车、订单一致,所以会话通常在TCP连接上进一步封装,在应用层提供。
3.TCP协议是一个面向连接的协议(Connection -oriented Protocol),说的就是TCP协议参与的双方(Host)在接收数据之前就会创建连接。我们之后还会学习UDP协议,UDP是一个面向报文(Datagram-oriented)的协议,协议双方不需要创建连接,直接传送报文(数据)
4.最后连接需要消耗资源;比如说,在传输数据前,必须协商创建连接。因此,不是每种场景都应该用连接导向的协议。像视频播放的场景,如果使用连接导向的协议,服务端每向客户端发送一帧视频,客户端都要给一个响应,这是不合理的
TCP为什么握手是3次、挥手是4次?
【解析】TCP是一个双工协议,为了让双方都保证建立连接的时候,连接双发都需要向对方发送SYC(同步请求)和ACK(响应),握手阶段双方都没有繁琐的工作,因此一方发出SYC之后,另一方可以将自己的ACK和SYC打包作为一个消息回复,因此三次握手时需要三次数据传输。
到了挥手阶段,双方都有未完成的工作。收到FIN请求的一方,必须马上响应(ACK),表示收到FIN请求。类比现实当中你收到一个Offer,出于礼貌先回复考虑一下,然后思考一端时间在给HR最后的回复。等待所有的工作都处理完成,再发送请求中断(FIN),因此是四次挥手。
思考题
一台内存8G左右的服务器可以同时维护多少个连接?可以在评论区写下你的思路和答案
网友评论