TCP & UDP

司马彦
2023-12-01

TCP是一种面向连接的传输协议,它安全、可靠、有序。需要经过3次握手连接(双方确认连接上),4次握手断开(服务器确保把数据全发送到客户端后才断开)。

UDP是一种无连接的传输协议,他虽然没有TCP的众多功能与优点,可他的传输速度比TCP要快不少。

1.通信数量:

UDP既支持一对一的单播,也支持一对多的广播。

TCP则只支持一对一的通信。客户端与服务器建立了一条可靠的通信连接。

2.报文处理:

UDP是把整个报文+上首部就完整的发送出去,接收端只需要去掉首部,就是完整的报文内容。UDP的报文既不合并也不拆分。

TCP会把数据块转换为字节流,然后存储到需要发送的缓存队列中,然后根据事先设置好的一些长度参数从缓存中获取一定数量的字节(这“一定数量”,可能少于一个数据块,也可能会是多个数据块)构建TCP报文再发送给接收方。

如:一个数据块10字节,一次发送22字节,那么第一次就会发送2.2个数据块。

接收方可以根据头部记录的数据长度,把接收到的数据从新分割成完整的数据块。(其实就是处理粘包问题)

3.可靠性:

UDP:在传输过程中,如果由于路由器丢了数据,或者数据错误等原因而导致数据丢失,UDP本身是不会做任何处理的。

TCP:是安全可靠的面向连接传输,不会出现误码、丢失、乱序、重复等问题。

1.TCP需要建立连接才能传输。

2.TCP会根据缓存大小进行数据分段和流量控制。

3.TCP会有端到端的校验,出错了也有重传机制。

4.TCP在收到准确数据后,会发送确认消息,超时了也会有重传机制。

4.传输速度:

UDP:UDP传输比较简单,高效,所以速度比较快。

TCP:正因为TCP的种种可靠的优点决定了他的传输速度会比UDP慢。如:TCP是有序的,所以当一个数据丢失后,后面的数据不会继续传输,会等待上一个数据重新发送或者收到后才会继续发送后面的消息;  客户端在确认收准确的数据后还要发送确认消息给服务器…… 等等。 正正认为TCP的各种复杂验证机制让TCP的数据来的更加安全可靠,但同样也让TCP的传输速度会慢于UDP。

5.封装UDP

拿TCP来做个比喻,他就像一个装备精良且统一制式的士兵,通过设置socket参数可以帮士兵配置不同的武器装备,而且都是一些制式的武器装备(规格模式统一,而且不容易出错)。

而UDP呢,就比较像一个身上没任何装备的士兵,所以他比TCP这位全副武装的士兵更加灵活敏捷(传输速度更快)。

当我们要求传输数据的速度尽可能快时(如一些格斗类游戏,需要快速反馈玩家的操作),往往我们选择UDP的效果会比TCP好很多。但我们又需要能顺序执行服务器发送的数据,也需要数据不丢失等功能时,我们就可以自己“定制武器装备”,再装配到这个“无装备的士兵”身上,让他变成适合我们项目使用的特种兵!

1.UDP数据包无序问题:

我们可以在数据包内自己组装一个头部,头部的其中一块局域添加一个自增的值,每次发送UDP数据时这个值就+1,客户端收到数据后,本地缓存把数据缓存起来,根据这个自增的值进去排序,就可以得到有序的数据了。

2.丢包问题:

最常规的手段就是ACK确认了,但要等到确认后才发送下一个数据包,这和TCP有什么区别?一样的慢……

我能想到的优化方案如下:

planA:优化一下ACK的策略,客户端定时发送消息给服务器,告诉服务器我当前收到的自增值的最大值和中间缺失了(不连续,跳开)的自增值,而服务器就可以再次补发缺失的UDP了。

planB:假设每个UDP的数据量都很少很少,那么我们在组装数据时,可以把前几个数据包的数据都组装进去(例如前4个数据包的数据),那么发送一条UDP的数据,里面就包含当前这条数据以及前4条数据了,只要5个数据包里面收到其中一个,都可以收齐所有数据,不用重新补发数据。 这个缺点显然就是发送的数据量会大很多,所以要求是每个数据包的数据量都很少。

PS:无论何种方案,结合具体项目情况来设计,才是最理想的方案。

 类似资料: