TCP和UDP
TCP和UDP简介
TCP
和 UDP
都工作在 OSI
参考模型的第四层(传输层),其目的都是为了都是为了实现端到端的传输,传输各种文件。
TCP
TCP
的实现是基于连接的可靠数据通信。
TCP
进行传输,每一次数据的发送都需要得到对应的回应,是否接受数据、接受状态如何、数据顺序是否出错等等,在建立连接的基础上实现传输。
UDP
UDP
提供基于无连接的尽力而为的通信服务。
UDP
进行传输,只管将数据发送出去,但是不确定对方是否能够接受或者已经接受。UDP
只能尽自己的能力去发送,实现无连接的数据传输。
TCP连接过程
TCP
基于连接进行数据传输,主要过程有三步:三次握手、数据传输、四次挥手。
三次握手
TCP
三次握手是建立 TCP
连接时使用的一种协议。在进行数据通信之前,客户端和服务器之间需要通过三次握手来确认彼此的可靠性,以确保双方都准备好传输数据。以下是 TCP
三次握手的详细过程:
- 第一次握手:客户端向服务器发送一个带有
SYN
(同步序列编号)标志的数据包,表示请求建立连接。此时客户端进入SYN_SENT
状态。 - 第二次握手:服务器收到客户端发送的 SYN 数据包后,会回复一个带有
SYN
和ACK
标志的数据包作为响应。ACK
是确认号,表示对客户端的SYN
请求做出确认,并且自己也想要建立连接。此时服务器进入SYN_RECV
状态。 - 第三次握手:客户端收到服务器的响应后,会再次发送一个带有
ACK
标志的数据包给服务器,表示对服务器的确认。此时客户端和服务器都已经确认了彼此的请求,连接建立完成,双方可以开始进行数据传输。客户端进入ESTABLISHED
状态,服务器在收到客户端的ACK
后也进入ESTABLISHED
状态。
简单来说就是:
客户端要送牛排,它把做好的牛排切条分盘,并把每盘编号。送到窗口让服务端去送,服务端为了保证这些盘的牛排是它负责送的,就将这些盘的牛排连编号拍了个照发给厨师客户端看并问了句这是它负责送的吗(
ACK
),客户端一看照片盘子编号、牛排条都对得上,就回服务端是(ACK
)。于是两边就都确认了彼此工作没问题,互相信任对方(进入 ESTABLISHED 状态,这里可能比喻的不太对)
数据包来回传输本质就是用来确认传输是否成功的,客户端发送数据包(序列号+字节数据),服务端返回给客户端两者的和进行确认。保证可靠性
这样就构成了TCP三次握手。但这个过程中实际上接收方可能会因为处理数据能力不强或者带宽资源不够等因素导致数据溢出,传输数据失败。于是要控制好每次传输分包的个数。这也是为什么会有滑动窗口、拥塞控制等技术,目的就是为了控制好分包的个数。
四次挥手
TCP
四次挥手是在数据传输结束后,客户端和服务器断开 TCP
连接时使用的协议。通过四次挥手,双方可以优雅地关闭连接,并确保数据的完整性。以下是 TCP
四次挥手的详细过程:
- 第一次挥手:客户端发送一个带有
FIN
(结束)标志的数据包给服务器,表示客户端已经完成了数据传输并准备关闭连接。客户端进入FIN_WAIT_1
状态。 - 第二次挥手:服务器收到客户端发送的 FIN 数据包后,会回复一个
ACK
数据包作为确认。此时服务器进入CLOSE_WAIT
状态,表示服务器已经知道客户端想要关闭连接。 第三次挥手:一段时间后,服务器也准备好关闭连接时,服务器会发送一个带有 FIN 标志的数据包给客户端,表示服务器也准备关闭连接。服务器进入
LAST_ACK
状态。第三次挥手要等一段时间是为了等客户端接收完服务端传输的数据,这样做能避免客户端因网络IO、带宽速度等原因导致数据接收缺失。
- 第四次挥手:客户端收到服务器的
FIN
数据包后,会回复一个ACK
数据包作为确认。此时客户端进入TIME_WAIT
状态,等待一段时间以确保服务器收到了最后的确认。服务器在接收到客户端的ACK
后就进入CLOSED
状态,连接完全关闭。
通过这个四次挥手的过程,客户端和服务器都可以完成连接的关闭,释放资源并终止对方的连接。在最后一次挥手完成后,双方的连接就正式关闭,不再传输数据。这种机制可以避免出现半开连接的情况,确保连接的安全关闭。
综上
通过这个三次握手过程,客户端和服务器能够建立起可靠的连接,并且双方都确认了彼此的通信能力。这种机制可以有效地防止因网络延迟或丢包等问题导致的连接异常,从而确保数据传输的可靠性。在数据传输结束后,双方可以通过四次挥手来关闭连接。
UDP连接过程
相比于 TCP
,UDP
的连接过程就很简单。
在原有数据包的基础之上,加上一些带有标识性的信息段,再通过网卡进行传输,之后不再关注该数据包的状态,从本质上来说,这些数据包之间并没有实质上的联系。所以,UDP
的数据包传输对于设备的计算损耗来说相当的小,可以大大的提高数据的传输速率。
举个简单的例子:
UDP
协议就相当于寄快递,将想要寄的东西(数据)打包好贴上地址联系人啥的(标识性信息段)给快递公司邮寄(网关)就行,之后的事就不用你再去关注了。
对比TCP和UDP
从上述 TCP
和 UDP
的介绍我们就知道,实际使用上虽然 UDP
能够根据他的特性快速进行数据传递,但同时来说相比于 TCP
,它不能保证数据的稳定性与可靠性。换句话说,UDP
只有简单的网络收发能力,保证了它快;TCP
拥有重传、滑动窗口、拥塞控制等可靠性机制保证可靠性。TCP
就像套了多层壳的 UDP
,可靠但是臃肿,速度慢了。
因此,TCP
的头部比UDP
要大得多,TCP
的头部大小最小是20字节,而UDP
头部固定是8字节大小。
简介概括起来:UDP
快,但是不稳。TCP
相对慢,但是又稳又可靠。
TCP 面向连接(如打电话要先拨号建立连接); UDP 是无连接的,即发送数据之前不需要建立连接。
TCP 要求安全性,提供可靠的服务,通过TCP连接传送的数据,不丢失、不重复、安全可靠。而UDP 尽最大努力交付,即不保证可靠交付。
TCP是点对点连接的,UDP一对一,一对多,多对多都可以
TCP传输效率相对较低,而UDP传输效率高,它适用于对高速传输和实时性有较高的通信或广播通信。
TCP适合用于网页,邮件等;UDP适合用于视频,语音广播等
TCP面向字节流,UDP面向报文
↑ UDP 没有确认号之类的可靠性保护内容,它的内容可能都是乱的,它会将应用层传输到传输层的报文直接封装成数据段传输到网络层,不同的数据段之间会有明显的边界,而不是像 TCP 那样会对报文进行分片传输,TCP 传输的是有序列号和字节数据的字节流。(应用层可以给乱序的数据进行整理,所以还是可以不怎么用担心乱序问题)
UDP使用场景
通过上述,我们可以得出 UDP 适用于数据量小,但是高频发送的场景,且不那么要求数据可靠性与完整性的场景。
例如DNS服务就用的 UDP,DNS 服务为了保证查询效率,小数据量,要的是结果和效率,就很适合 UDP 大展身手。简单高效。还有例如语音软件和视频聊天等场景,即便数据传输导致卡一会也不怎么影响功能使用的,也适合 UDP 大展身手。
简单介绍KCP
那有什么办法保证又快又稳定?创建网络协议的人就在 TCP
和 UDP
之间折中了一下,诞生了 KCP
。
KCP
简单来说就是少套了几层壳的 TCP
,但更准确的说是保留少数几个重要的壳的 UDP
。
KCP
可以算是一种协议,但本质上来说是一种应用层算法。
重传机制
KCP
为了缓解 UDP
的丢包问题,使用了重传机制
,这点与 TCP
相似。KCP
相比于 TCP
只需要等待1.5个 RTO
就能触发超时重传
,传统 TCP
需要等2个 RTO
。
KCP
采用的是快速重传机制。TCP
需要有三个为1
的 ACK
数据包才能触发重传
;KCP只需要二个为1
的 ACK
数据包就能触发重传
。
拥塞控制
TCP
检测到有丢包就会认为网络环境差,减少数据包传输的量。
KCP
也有这个策略,但不一样的是, KCP
可以关闭拥塞控制
。当网络环境变差时,TCP
减少数据包传输的,这时候 TCP
进行拥塞控制
相当于变相将网络资源让步给关闭拥塞控制
的KCP
。
例如:如果使用了 KCP
的实时监控视频网站,那么即便因网络问题视频数据传输丢包,也能通过 KCP
的特性让原本卡顿不清晰的画面变得相对清晰且流畅。
KCP的一些问题
这里重说回 KCP
的问题,在国内运营商内 UDP
传输的数据包如果在网络差的环境下是优先被丢弃的。如果要解决这种问题,一种是自己搭一个虚拟网络群,实现异地组网保证网络带宽高速且稳定。这一种解决方法技术要求和花费的成本都非常高。
KCP
其实本质上是介于用户代码
与 UDP
之间的算法中间层,我们可以在 UDP
和 KCP
之间加入前向纠错
这一中间层来进行优化。这种做法是在数据包里冗余其他数据包的信息,这样就算有些数据包丢失了,也能通过其他数据包内冗余的信息去进行一部分的丢失信息还原。这样能保证在弱网环境下也能流畅的运行网络需求高的软件。
另外,在现在的时代里,
UDP
协议使用的逐渐比TCP
协议要多。这实际上并不是TCP
不好,而是在现在网络硬件升级的越来越厉害、网络情况越来越好的时代下,TCP
那保持可靠与稳定性的各种机制反而显得TCP
变得愈发的臃肿。所以这也是为什么
UDP
正在逐渐的取代TCP
的原因。
评论(0)