前言
昨天迎来了第一场面试,对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包,刷新超时时间。
第四次挥手
超时连接时间片结束后,客户端关闭连接。