面试常问—TCP和UDP

183 阅读5分钟

前言

昨天迎来了第一场面试,对TCP和UDP的问题答的一塌糊涂,今天好好整理一下TCP和UDP相关的知识。

TCP和UDP是哪一层协议

TCP和UDP都是传输层协议,他们的目标是在程序之间传输数据(文本、图片、视频),这些数据都是二进制的

TCP和UDP区别

基于连接和基于非连接

  • TCP是基于连接的,就像打电话,不管是电话接通、互相通话、结束挂断都能得到很好的反馈,能确认对方准确的接收到

  • UDP是基于非连接的,就像写信,不知道对方是否能收到,收到的内容是否完整,顺序是否正确,你填写的收信人和收信地址是否存在都无法确认

可靠服务

  • TCP传送的数据,无差错,不丢失,不重复。TCP适合大数据量的交换

  • UDP发送数据,就是把数据包简单的包装一下,从网卡发出去。数据包之间没有状态上的联系,所以UDP不能保证完美交付

用途

  • TCP传输数据稳定可靠,但对网络要求较高的场景,需要准确无误的将数据传给对方,比如传输文件、发送邮件、浏览网页等

  • UDP虽然速度快,但是会出现丢包情况,适用于实时性要求高的场景,比如域名查询、语音通话、视频直播等

TCP传输

三次握手

三次挥手是确认连接的过程

  • 当客户端向服务端发起连接时,会发送一个连接请求数据包(SYN包),询问服务端能否建立连接

  • 如果服务端同意连接,则回复一个SYN+ACK包,告诉客户端你可以和我建立连接

  • 客户端收到SYN+ACK包后,回复服务端一个ACK包,连接建立

为什么是三次握手不是两次握手

服务端回复完SYN+ACK就建立连接,会导致已失效的报文突然传到服务端,引起错误

假设客户端向服务端发送一个SYN包,因为未知原因没有到达服务器,在中间某个网络节点滞留,为了建立连接,客户端再次发送SYN包,这次客户端与服务端建立连接。

建立连接后,滞留的SYN包到达服务端,服务端以为客户端又发送一次连接请求,那么此时服务端认为和客户端建立了两条连接,而客户端只认为建立了一条,造成了状态不一致。

如果在三次握手的情况下,服务端收不到最后的ACK包,就不会认为连接建立成功。三次握手就是为了解决网络信道不可靠的问题

传输确认

TCP协议需要在不可靠的信道上保证可靠的连接,那就有几种问题要面对

丢包问题:一包数据有可能会被拆成多包发送

乱序问题:数据包的先后到达顺序不同

为了解决这些问题,TCP建立了一个发送缓冲区,从建立连接后的第一个字节序列号为0,后面每个字节的序列号加1。从发送缓冲区选取一部分内容作为数据内容,在TCP协议头中加入序列号和长度,接受端在收到数据后需要回复确认报文,确认报文中的ACK = 序列号 + 长度,也就是下一次发送的起始序列号,这样一问一答的方式,能够使发送的数据已经确认被收到。

发送端也可以一次发送连续的多包数据,接收端只需要回复一次ACK,这样发送端可以把待发送分割成一系列的碎片发送到对方,根据序列号和长度进行重组,如果发生部分丢失,接收端发送丢失的起始序列号的报文,发送端收到后重传这部分数据,接收端进行补齐。

TCP连接是全双工的,对两端来说均采用上述机制

四次挥手

处于建立连接状态的两端都可以发送连接关闭请求

第一次挥手

假设客户端发起连接关闭请求,客户端需要向服务端发一个FIN包,表示关闭连接,客户端进入终止等待1状态

第二次挥手

服务端收到FIN包后,发送一个ACK包,表示自己进入关闭等待状态。

客户端进入终止等待2状态。

此时服务端还可以发送未发完的数据,客户端还可以接收数据,待服务端发送完数据后,发送一个FIN包,服务端进入最后确认状态

第三次挥手

客户端收到FIN包后,发送ACK包,进入超时等待状态,经过超时等待后进入关闭状态。

服务端收到ACK包后进入关闭状态。

为什么客户端需要等待超时连接

因为要保证对方已经收到ACK包,如果客户端在发送完ACK包就关闭,而此时服务端没有接收到ACK包,就会一直处于最终等待状态。

如果客户端发送完ACK包后等待一段时间,这时服务端没有收到ACK包,会再次发送FIN包,刷新超时时间。

第四次挥手

超时连接时间片结束后,客户端关闭连接。