通过上一节的学习,我们知道了端口是用来标识机器上应用程序的地址。下面来学习传输层最重要的两大协议:UDP和TCP。本文核心目标是攻占UDP协议,不过简单的UDP协议可能几句话就可以说完,因此引入了一些其他内容,前方高能!哈哈哈。
一、两种协议
首先我们要了解为什么要有两种协议,一种不行吗?
由于我们在网络上传输数据的时候有两类需求:
第一类:可靠传输数据,不对速度有太高要求
第二类:立即传输数据,允许传输时丢失一些信息
关于第一类,就是对应着我们大多数的应用程序,比如网页,丢失一个数据包,页面可能就无法正确展示了;还有电子邮件、SSH软件、多数在线游戏等等,我们必须不惜一切代价接收每个发送的数据包。
至于第二类,相对第一类就少了佷多,主要是流媒体应用程序,例如互联网广播、互联网电视等,此类场景用户可以忍受偶尔的断断续续,因此丢失一个或多个数据包,没有什么影响。
综上,我们的先辈发明了TCP协议,对应着第一类应用。TCP协议是基于连接的可靠的协议。就像打电话一样,首先通过“您好/喂/Hello/米西米西”之类的词语确定对方听得到,对方也会“喂/您好/米西米西”确定我能听得到。如果电话过程中有沉默,会再次询问对方在不在。并且对于后面的说话,都要有对方的回应,否则就要再重说一遍。TCP本质上就是实现了以上类似的场景,不过机器不像我们人这么聪明,要保证这种可靠的通信,还是蛮复杂的,这也是TCP复杂的原因。未来的时光,我们打交道最多的就是TCP协议了。
相对于TCP,UDP就简单了佷多,因为不可靠,就像寄信,我哗哗哗寄出去几十封就不管了,剩下了就看邮局给力不给力了,正常情况下最多也就丢一两封信件,我们对此表示可以忍受。但是最坏的情况下就是发出去的信一封都没到对方手中。但是没办法啊,我们只管发,才不管对方有没有收到呢,这才简单嘛,这样我们寄信速度是很快的,因为根本没有确认的过程,发了就完事了!因此这也不可靠嘛!所以我们经常说UDP是一个无连接、快速但不可靠的协议。
二、UDP协议
本节自然先聚焦简单的UDP协议。UDP的全称是:"User Datagram Protocol "
,即用户数据报协议。
UDP是很简单的协议,目标是快速发出去,不需要知道信息是否被正确接收,因此发送的报文也极其简单!下面将会看到。
2.1 DNS协议和nslookup命令
老规矩,我们来抓个实际报文来瞅瞅。我们先来学习一个知识点:DNS协议。
知识点1:DNS是什么?作用是什么?
这个DNS协议全称是Domain Name System
,中文翻译是域名系统。主要是负责将域名解析为实际的IP地址。因为我们的网络层进行路由的时候,是根据目的IP去进行路由的,这一点在我们学习网络层的时候已经很清楚了。比如我要访问www.baidu.com
的时候,第一步是走DNS服务器进行域名解析,变成IP地址。
此外,我们需要知道DNS是支持UDP或者TCP的,默认是基于UDP协议,因此我们可以借助域名解析的过程顺便来看下UDP的报文结构。也顺便学习下域名解析过程。
知识点2:nslookup命令
nslookup
命令用于查询DNS的记录,查看域名解析是否正常,在网络故障的时候用来诊断网络问题。
这个命令很简单,有两种交互模式:交互式和非交互式。下面用一张图来说明:
我们来看下非交互式显示结果的各行的含义:
这里涉及两个名词:别名和A记录。
2.2 别名和A记录
什么是别名?就是www.baidu.com
这个域名映射到了另一个域名,这里是www.a.shifen.com
。然后www.a.shifen.com
会有多条A记录,记录的是www.a.shifen.com
与IP地址的记录。
为什么要用别名?不是多此一举嘛?比如A解析为B再解析为实际IP,那我为什么不直接将A解析为实际IP呢?还少一次解析呢!
事实上,cname
很重要!由于对于CDN服务,比如我这里的的笔记图片是上传到七牛云上的。比如我的一张图片地址是:
http:
那么我这里的加速域名是如何利用七牛云CDN进行加速访问的呢?这里所谓的CDN加速,其实就是利用CDN自己的调度,使得用户访问某个资源的时候可以从最近的CDN节点上获取,从而实现加速效果。
那么我就在这里说说配置过程吧,从配置过程我们就会知道如何如何使用cname和为什么要用cname了!
首先,我需要申请一个域名,我是在腾讯云服务器平台上申请的,大家可以选择平台申请。我的个人域名是oursnail.cn
。
由于七牛云使用图片的时候,必须要用正式的域名,当然了,如果你没有域名,七牛云会给你提供一个临时的域名,不过这个域名好像使用时间不长,过期的话,不好意思,你的图片都无法正常访问了。
因此申请自己的域名是第一步必要步骤!我为博客的图片设定的域名是bloghello.oursnail.cn
。
这里就是一个二级域名,其实很简单,我举个例子就知道了。比如我有一个个人商城网站,前台门户访问地址是www.oursnail.cn
,后台管理系统访问地址是admin.oursnail.cn
,那么如何区分为这两个域名呢?答案就是在云服务器上添加主机记录即可:
由于我们只有一台云主机,所以解析到的地址即记录值都是我们这台云主机的公网IP地址。然后实际上我们还要借助nginx
这个软件来根据不同的访问的域名解析到不同的tomcat
服务上,最终达到上面的效果。
好了,言归正传,我们回到bloghello.oursnail.cn
这个二级域名,记住,这个域名是我们自己的。下面我们的图片上传到七牛云上了,我们的这个域名如何跟七牛云挂钩起来呢?
所以啊,这里用到了cname,根本原因就是我们的域名是我们自己的,但是要用七牛云的服务就得用七牛云的域名。我在腾讯云服务器上这样添加的:
首先你会说:还是老问题啊,你为什么不直接解析到七牛云的IP上呢?
答案就是:IP地址可能会变化,因为如果IP直接写死,那么如果七牛云的IP发生变化,每个用户都需要去做改动,否则就会有问题。那么用cname就完美解决了这个问题:你用你自己的域名,反正指向的是七牛云的一个域名,域名不会变化,但是七牛云可以随便改变自己的IP,而不会对用户产生任何影响。这就是别名的威力!七牛云上是这样解释的:
好了,上面提到我把bloghello.oursnail.cn
解析到了一个很长的域名上bloghello.oursnail.cn.qiniudns.com.
,这个域名是你在七牛云上自定义CDN加速域名的时候,七牛云在后面自动拼接而成。
经过上面的设置,我访问图片:http://bloghello.oursnail.cn/network15-2.png
的过程中,第一步是把域名bloghello.oursnail.cn
解析为别名即cname:bloghello.oursnail.cn.qiniudns.com
,然后这个域名是有对应的A记录的,即可以直接解析为IP地址。七牛云在后面的一步可以帮助我们根据地区自动实现CDN的调度,从而完成加速。
我们再来用nslookup
命令来解析bloghello.oursnail.com
这个域名,看看是不是我们上面说的过程。这次我们可以指定DNS服务器来看解析结果,比如我指定咱们电信的公共DNS:114.114.114.114
。
我们可以看到,有一个别名叫做bloghello.oursnail.cn.qiniudns.com
。这里的aliases
就是别名的意思,不过这里的结果是不是有点复杂了?咋还有其他的域名呢?并且应答里面的咋是tinychinacdnweb.qiniu.com.w.kunlunno.com
呢?
不急,我们先来看下简单的,看下百度,搬来nslookup
的结果图:
我们可以理解,www.baidu.com
指向了www.a.shifen.com
,然后www.a.shifen.com
对应有一条A记录即180.101.49.11
这个地址。
这个我们可以借助dig
命令更加详细地了解,我找来一个linux
服务器来执行这条命令来看看结果:
第一部分显示
dig
命令的版本和输入的参数。第二部分显示服务返回的一些技术详情,比较重要的是
status
。如果status
的值为NOERROR
则说明本次查询成功结束。第三部分中的
"QUESTION SECTION"
显示我们要查询的域名。第四部分的
"ANSWER SECTION"
是查询到的结果。第五部分则是本次查询的一些统计信息,比如用了多长时间,查询了哪个
DNS
服务器,在什么时间进行的查询等等。
那么我们同理来看看bloghello.oursnail.com
的dig
结果:
从dig
的结果来看里面的过程,就显得很清晰了,原来七牛云内部cname
了三次呢!我们在设置上只要完成第一步的cname
即可,剩下的全交给七牛云内部来实现。
因此也可以看到dig
命令是比nslookup
命令更加强大的!
好了,至此,别名和A记录说明完毕。为什么用别名想必说明的已经很清楚了。
2.3 回到UDP
上面说了一大段,其实跟我们这里的主题关系不大,不过也是很重要的一部分内容。说了这么多就是为了防止看咱们这里的UDP的报文看不懂,因为我们这里借助了nslookup
命令来抓UDP报文的。现在已经可以回归主题了。
好了,这个是DNS部分的内容,下面真的是UDP的内容了!
没错,就这么几个字段:源端口号、目的端口号、数据报总长度、校验和。
每个区域都占 2 个字节,所以头部只需要 8 个字节。这是我们迄今为止看到的最小的头部了,以后应该也看不到比这更小的头部了。
源端口号(
Source Port
):这很简单,它是发送信息的应用程序的地址。目标端口号(
Destination Port
):也很简单,它是接收信息的应用程序的地址。数据报的总长度(单位是
Byte
):此区域占 2 字节,这意味着一个数据报的最大长度是 2 的 16 次方(等于 65536)个字节。但现实中,很少见到大于 512 字节的 UDP 数据包。这主要是因为丢失一个较小的数据报是可以接受的,但是丢失较大的数据报则比较麻烦,因为 UDP 对于丢失数据包置若罔闻。Checksum
:表示 “校验和”,其原理与 OSI 第 2 层的以太网帧里的CRC
(循环冗余校验)类似,也是为了确保发送的数据和接收的数据是相同的。也许有些教材将这里的Checksum
写成CRC
。CRC
和Checksum
都属于冗余校验(Redundancy Check
)。Checksum
是最简单的冗余校验。
对了,既然
OSI
第 2 层以太网协议已经有一个CRC
校验了,为什么UDP
协议还需要有一个Checksum
校验呢?
OSI每一层都是独立的,校验了第二层并不意味着不需要校验第四层,第三层也同理。因为每一层都不应该知道另一层执行了一个校验,每个层应该实现自己的校验。此外,有时数据报到达第 4 层时,会带着从第 3 层跨越到第 4 层时产生的错误。因此,使用冗余校验是非常必要的。
好了,UDP就学习完毕了。
三、总结
我们在网络上传输数据的时候有两类需求:第一类:可靠传输数据,不对速度有太高要求;第二类:立即传输数据,允许传输时丢失一些信息。
TCP就像打电话,对应第一类场景,强调的是可靠;UDP就像寄信,对应第二类,强调的是简单快速。
DNS协议全称是
Domain Name System
,中文翻译是域名系统。主要是负责将域名解析为实际的IP地址。DNS是支持UDP或者TCP的,默认是基于UDP协议。nslookup
命令用于查询DNS的记录,查看域名解析是否正常,在网络故障的时候用来诊断网络问题。这个命令很简单,有两种交互模式:交互式和非交互式。dig
命令是比nslookup
命令更加强大的!CNAME
记录和 A 记录都是在 DNS 解析过程中的一种记录值类型。A 记录会直接解析到某个 IP ,CNAME
会解析到另一个域名,之后再对另一个域名继续解析,直到解析出节点。所以,A 记录只能够实现域名解析到 IP。CNAME
的作用:如果直接将域名解析为IP即A记录的方式好像也没啥毛病,但是IP地址可能会变化,因为如果IP直接写死,那么如果七牛云的IP发生变化,每个用户都需要去做改动,否则就会有问题。那么用cname就完美解决了这个问题:你用你自己的域名,反正指向的是七牛云的一个域名,域名不会变化,但是七牛云可以随便改变自己的IP,而不会对用户产生任何影响。这就是别名的威力!UDP的报文头包含:源端口号、目的端口号、数据报总长度、校验和。
数据报的总长度(单位是
Byte
):此区域占 2 字节,这意味着一个数据报的最大长度是 2 的 16 次方(等于 65536)个字节。但现实中,很少见到大于 512 字节的 UDP 数据包。这主要是因为丢失一个较小的数据报是可以接受的,但是丢失较大的数据报则比较麻烦,因为 UDP 对于丢失数据包置若罔闻。为什么每一层都要做校验?OSI每一层都是独立的,校验了第二层并不意味着不需要校验第四层,第三层也同理。因为每一层都不应该知道另一层执行了一个校验,每个层应该实现自己的校验。此外,有时数据报到达第 4 层时,会带着从第 3 层跨越到第 4 层时产生的错误。因此,使用冗余校验是非常必要的。
四、重要链接
CDN到底是个什么鬼?看完这篇你就懂了!
linux dig命令
如何配置域名的 CNAME