本文主要介绍计算机网络OSI模型中传输层协议TCP(Transmission Control Protocol)与UDP(User Datagram Protocol)的区别、各自的使用场景,以及面试中经常出现的一系列问题。Let's go!
相较于UDP,TCP的特点可以归纳为:面向连接、字节流传输以及可靠传输。
使用TCP协议通信的双方在传输数据之前,必须先建立一对一的连接,并且这个连接是全双工的,双方可以在一个连接上完成数据读/写,完成数据交互后,双方必须断开连接以释放系统资源。所以,在这期间通信双方会产生资源开销以维护、管理连接的状态(读写缓冲区、定时器等等)。
基于字节流传输的数据没有长度限制,就像一根无限长的水管一样,数据可以源源不断的从通信的一端流向另一端,发送端可以逐个字节的向数据流中写入数据,接收端也可以逐个字节的从数据流中读出数据。TCP通信双方的读/写数据次数不一定相等,发送端在连续进行写操作时,TCP模块会先将数据放入TCP发送缓冲区,等待真正发送数据的时候,将发送缓冲区中的数据组成一个或者多个报文段发出。同样地,接收端也拥有TCP接收缓冲区,接收端收到一个或多个报文段后按序依次放入接收缓冲区,可以一次性读取全部数据或分多次读取,这取决于用户指定的读缓冲区大小。
TCP是可靠传输依赖于以下几种机制:应答机制、超时重传、拥塞控制。
(1)应答机制
即TCP三次握手、四次挥手,发送端发送的每个TCP报文段都必须得到接收端的应答,才认为这个报文段传输成功。
(2)超时重传
TCP模块为每一个TCP报文段都维护一个重传定时器,发送端发出报文后启动重传定时器,在定时时间未收到应答,则重新发送该报文段。(关于重传定时器的定时时间以及如何重传都依赖于内核指定的重传策略,此处不做讨论)。
(3)拥塞控制
拥塞控制其实分为两部分,一部分是拥塞发生之前避免拥塞发生(慢启动、拥塞避免),另一部分是拥塞发生之后解决拥塞(快速重传、快速恢复)。
i.慢启动。TCP连接成功建立后,并不清楚网络的状况,以慢启动的方式更加平滑的发送数据,假设发送端此时最多发送X个报文段,此后每成功接受到一次确认信息都线性增大X的值。
ii.拥塞避免。由于慢启动会不断增加发送报文段的数量X,X越来越大必然会导致网络拥塞,因此TCP中定义了慢启动门限值来限制X的值,当超过门限值时,将启用拥塞避免算法,来减缓X的增大。
iii.快速重传。发送端连续收到三个重复的确认后重新发送丢失的报文段,并且减小慢启动门限值,避免拥塞。(引起接收端发送连续确认的原因可能有:报文段丢失、收到的报文段乱序)
iiii.快速恢复。当收到新数据的确认时,恢复因快速重传修改的慢启动门限值为初始状态。
相较于TCP,UDP的特点可以归纳为:实时性高、资源占用少、基于数据报。
在遇到网络拥塞时,UDP协议可以在应用层控制重传策略,减少重传间隔,超时时间后无法发送的数据直接丢弃。
UDP通信双方不需要保持长连接状态,没有三次挥手/四次挥手的过程,通信双方无需为了保持连接状态消耗资源。
UDP协议不会对应用层发送的数据进行拆分、合并,直接以数据报的形式发送到网络中。因此,使用UDP通信的双方协商好发送/接收的数据长度,才能完整的收发数据,并且一次数据发送必须对应一次数据接收。
1)TCP:文件传输、邮件传输
2)UDP:音视频通话,实时对战游戏,DNS解析过程
1)为什么建立TCP是三次握手,而断开连接是四次挥手?可以是三次挥手吗?
例如,客户端发出的close请求后发送一个FIN信息,服务端会回复一个ACK应答信息,告诉客户端,“我成功收到你的关闭请求了”,但此时不能立即断开连接,因为这时服务端可能还有需要发送给客户端的数据,再确认没有数据需要发送后,服务端也会发送一个FIN信息,告诉客户端连接可以关闭,如果客户端成功收到这个FIN信息并回复一个ACK应答信息,即可断开连接。期间移一共四次交互,所以是四次挥手。
可以看出,断开连接期间,服务器分别发送了一个ACK和FIN信息。其实,在FIN信息中包含ACK信息,所以一开始回复的ACK可以省略。是否省略取决于TCP的延迟确认特性(收到消息后,不会立即回复ACK确认信息,而是在一段延时后,查看本段是否有需要发送的数据,可以将数据与ACK信息一起发送出去,以此减少TCP报文段的数量,提升网络性能)
2)四次挥手完成后,连接立即断开吗?
从上面的TCP连接图中可以看出,在完成四次挥手后,连接并未立即断开,而是处于TIME_WAIT延时状态(这个时间一般是2MSL),一是客户端以此确认服务端收到发出的ACK应答信息,二是同一个TCP端口不能多次打开,如果此时立即断开,则有可能建立起一个与之相似的连接,可能接受到之前连接中存在的数据。
3)服务端和客户端如何判断连接已经断开?
read系统调用返回值为0.
4)TCP连接建立后,客户端发生故障怎么办?
TCP中设有一个时长2小时的保活计时器,如果服务端超过2小时未接收到客户端数据,会每隔一段时间发出多个探测报文,若无响应,则断开连接。
5)如何判断拥塞发生?
报文传输超时;收到重复的确认报文段;