网络:TCP与UDP
IP层之上就是传输层,而传输层比较重要的两个协议:TCP和UDP。对于不从事底层开发的人员来讲,或者对于应用开发的人来讲,最常用的就是这两个协议。
TCP和UDP有哪些区别
TCP是面向连接的,UPD是面向无连接的。
那什么叫做面向连接,什么叫做无连接呢?
在互通之间,面向连接的协议会先建立连接。比如,TCP会三次握手,而UDP不会
为什么要建立连接呢?你TCP三次握手,我UDP也可以发三个包玩玩,有什么区别吗?
所谓的建立连接,是为了在客户端和服务端维护连接,而建立一定的数据结构来维护双方交互的状态,用这样的数据结构来保证所谓的面向连接的特性
- 比如,TCP提供可靠交互。通过TCP连接传输的数据,无差错、不丢失、不重复,并且按序到达。 IP包是没有任何可靠性保证的,一旦发出去,就像西天取经,走丢了,被妖怪吃了,都只能随它去了。但是TCP却能够保证可靠交付,而UDP继承了IP包的特性,不保证不丢失,不保证按顺序到达
- 再如,TCP是面向字节流的。发送的时候发的是一个流,没头没尾。IP包可不是一个流,而是一个个IP包。之所以变成了流,这也是TCP自己的状态维护做的事情。而UDP继承了IP的特性,基于数据报的,一个一个的发,一个一个的接收
- TCP是可以有拥塞控制的。它意识到包被丢弃了会在网络的环境不好了,就会根据情况调整自己的行为,看看是不是发块了,要不要发慢点。UDP就不会,应用让我发,我就发,管它洪水滔天
- 因而TCP其实是一个有状态服务,也就是说它是有脑子的,里面精确的记着发送了没有,接收到了没有,发送到哪个那,应该接收哪个了,错一点而都不行,而UDP是无状态服务,发出去了就发出了,不会去记忆
我们可以这样比喻,果MAC层定义了本地局域网的传输行为,IP层定义了整个网络端到端的传输行为,这两层基本定义了这样的基因:网络传输是以包为单位的,二层叫做帧,网络层叫做包,传输层叫做段。我们笼统的称为包,包单独传输,自行选路,在不同的设备封装解封装,不保证到达。基于这个基因,生下来的UDP完全集成了这些特性,几乎没有自己的思想。
UDP
- 当我发送的UDP包到达目标机器后,发现MAC地址匹配,于是就取下来,将剩下的包传给处理IP层的代码。把IP头取下来,发现目标IP匹配,接下来呢?这里面的数据报是发给谁呢?
- 发送的时候,我知道我发的是一个UDP的包,收到的那台机器是如何知道的呢?所以在IP头里面有个8位协议,这里会存放,数据里面到底是TCP还是UDP,当然这里是UDP。于是,如果我们知道UDP头的格式,就能从数据里面,将它解析出来。解析出来以后呢?数据给谁呢?
- 处理完传输层的事情,内核的事情基本就干完了,里面的数据应该交给应用程序自己去处理,可是一台机器上跑着那么多的应用程序,应该给谁呢?无论是应用程序写的使用TCP传输数据,还是UDP传输数据,都要监听一个端口。正是这个端口,要不说端口不能冲突呢。两个应用监听同一个端口,到时候包给谁呀?所以,按理说,无论是TCP还是UDP包头里面都应该有端口号,根据端口号,将数据交给响应的应用程序。
- 当我们看到UDP包头的时候,发现的确有端口号,有源端口号和目标端口号。因为是两端通信嘛。你还会发现,UDP除了端口号,再没有其他的了。和TCP比起来,这个简单的一塌糊涂啊
UDP的三大特点
UDP就像小孩子一样,有这些特点:
- 第一,沟通简单,不需要一肚子花花肠子(大量的数据结构、处理逻辑,包头字段)。前提是它相信网络世界是美好的,相信网络通路默认是很容易送达的,不容易被丢弃的
- 第二,亲信他人。它不会建立连接,虽然有端口号,但是监听在这个地方,谁都可以传给它数据,他也可以传给任何人数据,甚至可以同时传给多个人数据
- 第三,愣头青,做事不懂权变。不知道什么时候该坚持,什么时候该退让。它不会根据网络的情况进行包的拥塞控制,无论网络丢包丢城啥样了,它该怎么发还是怎么发
UDP的三大场景
基于UDP的这些特点,我们可以考虑在下面场景中使用:
- 第一,需要资源少,在网络情况比较好的内网,或者对于丢包不敏感的应用。
- 比如DHCP就是基于UDP协议的。一般的获取IP地址都是内网请求,而且一次获取不到IP有没事,过一会儿还有机会。
- PXE可以在启动的时候自动安装操作系统,操作系统镜像下载的时候使用的TFTP也是基于UDP协议的。在还没有操作系统的时候,客户端拥有的资源很少,不适合维护一个复杂的状态机,而且因为是内网,一般也没啥问题
- 第二,不需要一对一沟通,建立连接,而是可以广播的应用。
- UDP这种不面向连接的功能,可以使得承载广播或者多播的协议。
- DHCP就是一种广播的形式
- 对于多播,IP地址中有一个D类地址,也就是组播地址,使用这个地址,可以将包组播给一批机器。当一个机器上的某个进程想监听某个组播地址的时候,需要发送IGMP包,所在网络的路由器就能收到这个包,知道有关机器上有个进程在监听这个组播地址。当路由器收到这个组播地址的时候,会将包转发给这台机器,这就实现了跨路由器对的组播
- 第三,需要处理速度快,时延低,可以容忍少数丢包,但是要求即使网络拥塞,也毫不推送,一往无前的时候
- UDP简单、处理速度快,不像TCP那样,操这么多的心:各种重传、保证顺序、前面的收不到后面就没法处理呢。不然等这些事情做完了,时延早就上去了。而TCP在网络不好出现丢包的时候,拥塞控制策略就会主动的退缩,降低发送速度。
- 当前很多应用都是要求低时延的,它们可不想用TCP如此复杂的机制,而是想根据自己的场景,实现自己的可靠和连接保证。比如,如果应用自己觉得,有些包丢了就丢了,没必要重传;有的比较重要,则应用自己重传,而不依赖于TCP;前面的包没到,后面的先到了,那就先给客户展示后面吗,干嘛非得到齐呢;如果网络不好,丢了包,那不能推送啊,要尽快传啊,速度不能降下来嘛,要挤占带宽,抢在客户失去耐心之前到达。由于UDP十分简单,基本什么都没干,也就是给了应用“城会玩”的机会
基于UDP的“城会玩”的五个例子
网页或者ARP的访问
原来访问网页和手机ARP都是基于HTTP协议的。HTTP协议是基于TCP的,建立连接都需要多次交互,对于时延比较大的目前的驻留的移动互联网来讲,建立一次连接需要的时间会比较长,然而既然是移动中,TCP可能还会断了重连,也是很耗时的。而且目前的HTTP协议,往往采用多个数据通道共享一个连接的情况,这样本来为了加速传输速度,但是TCP的严格顺序策略使得哪怕共享通道,前一个不来,后一个和前一个即便没有关系,也要等着,时延也会加大。
而QUIC(即Quick UDP Internet Connections,快速UDP互联网连接)是google提出的一种基于UDP改进的通信协议,其目的是降低网络通信的延迟,提供更好的用户互动体验。
QUIC在应用层上,会自己实现快速连接建立,减少重传时延,自适应拥塞控制,是应用层城会玩
的代表
流媒体的协议
现在直播比较火,直播协议多使用RTMP,而RTMP协议也是基于TCP的。TCP的严格顺序传输要保证前一个收到了,下一个才能确认,如果前一个收不到,下一个就算包已经收到了,在缓存里面,也需要等着。对于直播来讲,显然是不合适的,因为老的视频帧丢了其实也就是丢了,就算在传过来用户也不在意了,他们要看新的了,如果老是没来就等着,卡顿了,新的也看不了,那就回丢失客户,所以直播,实时性比较重要,宁可丢包,也不要卡顿的。
另外,对于丢包,其实对于视频播放来讲,有的包可以丢,有的包不能丢,因为视频的连续帧里面,有的帧重要,有的帧不重要,如果必须要丢包,隔几个帧丢一个,其实看视频的人不会感知,但是如果连续丢帧,就会感知了,因而在网络不好的情况下,应用希望选择性的丢帧。
还有就是当网络不好的时候,TCP协议会主动降低发送速度,这对本来当时就卡的看视频来讲是要命的,应该应用层会马上重传,而不是主动让不去。因而,很多直播应用,都基于UDP实现了自己的视频传输协议。
实时游戏
游戏有一个特点,就是实时性比较高,快一秒你干掉别人,慢一秒你被别人爆头。因而,实时游戏中客户端和服务端需要建立长连接,来保证实时传输。但是游戏玩家很多,服务器却不多。由于维护TCP连接需要在内核维护一些数据结构,因而一台机器能够支撑的TCP连接数目是有限的,然后UDP由于是没有连接的,在异步IP机制引入之前,尝尝是应对海量客户端连接的策略。
另外还是TCP的强顺序问题,对战的游戏,对网络的要求很简单,玩家通过客户端发送给服务器鼠标和键盘行走的位置,服务器会处理每个用户发送过来的所有场景,处理完再返回给客户端,客户端解析响应,渲染最新的场景展示给玩家。
如果出现一个数据报丢失,所有事情都需要等待这个数据包重发,客户端会出现等待接收数据报,然而玩家并不关心过期的数据,激战中卡1s,等能动了就已经死了
游戏对实时要求较为严格的情况下,采用自定义的可靠UDP协议,自定义重传策略,能够把丢包产生的延时降到最低,尽量减少网络问题对游戏性造成的影响。
IoT物联网
一方面,物联网领域终端资源少,很可能只是个内存非常小的嵌入式系统,而维护TCP协议代价太大;另一方面,物联网对实时性要求也很高,而TCP还因为上面那些原因导致时延大。物联网协议thread就是基于UDP协议的
移动通信网络
在4G网络里面,移动流量上网的数据面对的协议GTP-U是基于UDP的,因为移动互联网比较复杂,而GTP协议本身就包含复杂的手机上线下线的通信协议。如果基于TCP,TCP的机制就显得非常多余。
TCP
TCP不像UDP,相信“网之初,性本善,不丢包,不乱序”。它天然认为网络环境是恶劣的,丢包、乱序、重传、拥塞都是常用的事,一言不合就可能送达不了,因而要从算法层面来保证可靠性
面试题:TCP和UDP的区别
一句话概括:TCP是面向连接的、UDP是无连接的。为此,它引出了极大不同:
- TCP是可靠的,UDP是不可靠的
- TCP是报文流、UDP是数据报
- TCP有网络拥塞控制算法,UDP是应用让它发它就发
- TCP有状态,UDP无状态
from:https://blog.csdn.net/zhizhengguan/article/details/121062793