TCP (传输控制协议) 和 UDP (用户数据报协议) 是两种常见的传输层协议。以下是它们的原理、实现方式以及使用场景的详细介绍。
Hi~!欢迎来到碧波空间,平时喜欢用博客记录学习的点滴,欢迎大家前来 指正,欢迎欢迎~~✨✨ 主页:碧波****
目录
TCP (Transmission Control Protocol)
[🔥 问题1:为什么是3次握手而不是2次握手。](#🔥 问题1:为什么是3次握手而不是2次握手。)
[🔥 问题2:如何处理丢包问题和乱序问题?](#🔥 问题2:如何处理丢包问题和乱序问题?)
[🔥 问题四:为什么建立连接是三次握手、断开连接是四次?](#🔥 问题四:为什么建立连接是三次握手、断开连接是四次?)
部分内容原文链接:TCP和UDP的区别(简单明了) -- 编程屋
前言
协议是什么?
协议就是双方通信都需要遵守的规则。
这个规则它规定了数据的格式、传输方式、错误处理等细节。
TCP (Transmission Control Protocol)
原理:
- 连接导向:TCP 是面向连接的协议,建立连接前需要进行三次握手(SYN, SYN-ACK, ACK)。
- 可靠传输:保证数据包按顺序到达,不丢失且不重复。使用确认机制和重传机制来实现。
- 流量控制:通过滑动窗口机制控制数据流量,以防止接收端被淹没。
- 拥塞控制:动态调整数据传输速率以适应网络的拥塞情况。
管理连接状态和数据传输的重要控制标志:
URG:紧急指针(urgent pointer)有效。
ACK:确认序号有效。PSH:接收方应该尽快将这个报文交给应用层。
RST:重置连接。
SYN:建立一个新连接。
FIN:断开一个连接。
实现:
- 三次握手:确保双方都准备好进行数据传输,并建立通信链路。
- 数据确认:每收到一个数据包,接收端都会发送确认信息;若发送端超时未收到确认,则重发数据包。
- 流量与拥塞控制:使用算法如慢启动、拥塞避免、快重传和快恢复来调整传输速率。
使用场景:
- 需要可靠数据传输的应用,如网页浏览、电子邮件、文件传输(FTP)和数据库查询。
三次握手
客户端向服务端发起连接时,会先发**一包连接请求数据(SYN包)**询问能否与你建立连接 (第一次握手)
如果对端同意连接则回复一包SYN+ACK包。(第二次握手)
客户端收到之后**,回复一包(ACK包),**连接建立。(第三次握手)
四次挥手
处于连接状态下客户端和服务端,都可以发起关闭连接请求,此时需要4次挥手来进行连接关闭。
客户端 主动发起连接关闭请求它需要将服务端发送FIN包,表示要关闭连接,自己进入终止等待1状态(第一次挥手)
服务端 收到FIN包,发送ACK包,表示自己进入了关闭等待状态,客户端进入终止等待2状态(第二次挥手)
服务端 此时还可以发送未发送的数据,而客户端还可以接收数据,待服务端发送完数据之后,发送FIN包进入最后确认状态(第3次挥手)
客户端 收到之后回复ACK包,进入超时等待状态,进入超时等待状态,经过超时时间后关闭连接,而服务端收到ACK包,立即关闭连接(第4次挥手)
UDP (User Datagram Protocol)
原理:
- 无连接:UDP 是无连接的协议,不需要在数据传输前建立连接。
- 不可靠传输:不保证数据包的顺序、完整性或可靠送达。数据包可能丢失、重复或乱序。
- 低延迟:由于缺乏握手和确认机制,UDP 延迟较低,适合实时通信。
实现:
- 数据报文传输:将数据打包成独立的报文进行传输,无需连接建立和维护。
- 简单的协议头:UDP 协议头比 TCP 简单,减少了开销。
使用场景:
- 需要快速、低延迟的应用,如在线游戏、视频会议、流媒体(如视频直播)、DNS 查询和实时数据传输。
重点问题分析
🔥 问题1:为什么是3次握手而不是2次握手。
如果使用两次握手,可能会遇到旧连接的问题。例如,某个连接由于网络延迟而未完全关闭,新的连接请求可能会误用旧连接的资源。三次握手可以有效地避免这种问题。
为了防止已经失效的请求报完。突然又传到服务器引起错误。
问题出现过程:
1.如果采用了两次连接,客户端向服务端发送了一个SYN包来请求建立连接,因为一些原因并没有到达服务器在中间某个网络节点产生了滞留。
2.为了建立连接客户端重新发送SYN包,这次数据包正常送达,服务端回复SYN+ACK后建立了连接。
3.但是第一包数据阻塞的网络节点突然恢复,又达到服务端。此时服务端认为是客户端重新发起了一个新的连接,从而在两次握手之后进入等待数据状态。
4.服务端认为是两个连接,客户端认为是一个连接,造成了状态不一致,如果在三次握手情况下,服务端在收不到ACK情况下,连接自然不会建立成功。
🔥 问题2:如何处理丢包问题和乱序问题?
1. TCP协议为每一个连接 建立了一个发送缓冲区,从建立连接的第一个字节号为0,后面每个字节的序列好就会增加1;
2.发送数据时,从发送缓冲区取一部分数据组成发送报文,在其tcp头中会附带序列号和长度;
3.接收端在收到数据后需要回复确认报文,确认报文中的ACK等于接收序列号加长度,也就是下一包数据需要发送的起始序列号;
4.这样一问一答的发送方式,能够使发送端确认发送的数据,已经被对方收到;
5.发送端也可以一次性发送多包数据,接收端只需要回复一次ACK就行了。这样发送端可以将待发送的数据分割成一系列的数据发送到对端,对端根据序列号和长度在接收后重构出完整的数据。
如果丢失了某些数据,可以要求发送端重传,比如丢失了100~199这100个字节接收端向发送端发送ACK等于100的报文,发送端发送后重传这包数据,接收端进行补齐,以上过程不区分客户端和服务端,TCP连接是全双工的,对于两端连接均采用上述机制。
🔥问题3:为什么客户端需要等待超时时间?
为了保证对方已经收到ACK,因为假设客户端发送最后一包ACK后就释放了连接,一旦ACK包在网路中丢失,服务端将一直停留在最后确认状态。
如果客户端发送最后一包ACK后等待一段时间,这时服务端因为没有收到ACK包,会重发FIN包,客户端会响应这个FIN包,重发ACK包并刷新超时时间,这个机制和3次握手一样保证不可靠的信道上建立起可靠的连接。
🔥 问题四:为什么建立连接是三次握手、断开连接是四次?
建立连接:使用三次握手是为了确保双方都已准备好并同步序列号。
断开连接:则需要四次挥手,主要是因为 TCP 连接的关闭是双向的,需要双方都确认关闭过程。
总结
- TCP:适用于需要可靠、顺序数据传输的场景,具有较高的开销但保证数据的准确性。
- UDP:适用于需要快速传输且可以容忍一定丢包的场景,具有较低的开销和延迟。