首先明确什么是数据包
在http2.0之后 ,一个完整请求所对应的所有数据叫做数据流,但是在实际发送过程中,一个数据流可能会比较大,无法一次性发送完,因此会将一个数据流分成多个数据包发送。
数据包从开始发送到发送结束要经过什么呢?总的来说可以分为以下几个阶段
粗略分析
准备数据包。虽然要发送,但是总得先知道要发送什么东西吧,先把要发送的数据包准备好。
找到传输目的地。发送地点不需要找,就在本地,但是要发到哪里去呢。
确认通信环境(这一步不是必要的,也可以不确认直接发送,出问题再说)。先看看路能不能走通,能走通我再把这个数据包发过去,走不通就别强行发过去了。
发送数据包。数据包准备好了,也知道要传输的目的地,中间的过程也探路清楚了,万无一失,可以开始发送数据包过去了。
那么下面就是具体对每个阶段的分析了:
具体分析
注意,以下几个阶段只是个人总结的逻辑上的顺序,在实际上是层层穿插的,不是完成了一个阶段才能进行下一步的。
1 准备数据包
数据包的准备离不开http,tcp,ip,mac协议的帮助。
首先,http请求发送后,响应的数据会被摘出来变成适合在网络中传输的格式;
第二,tcp协议会被这个数据加一层控制信息,包括端口号,序列号,确认应答号等,在将整个数据进行分段;
第三,每个数据段会进一步被ip协议进行封装,加上ip地址信息;
最后,由mac协议再包裹一层,前面加的都是网络上的信息,mac层加的是物理位置上的信息,负责手把手教你往哪里走。
经过重重包装,一个完整的数据包就诞生了,接下来就是准备发送了。
2 找到传输目的地
这个所谓的找到传输的目的地,即指找到目标的ip地址,也指找到目标的mac物理地址。
2.1 如何找到对方的ip地址呢
这就要涉及到域名是如何解析的了:拜托DNS服务器。
DNS服务器是包含了所有的域名与其对应的IP地址的关系,当然,这么多对应关系肯定是一个DNS服务器存不下去的,以https://www.csdn.com为例子,域名解析会从后往前,首先解析到com,拿com去找根域名服务器,得到com 顶级域名服务器地址,然后在解析到csdn,拿csdn.com去找com 顶级域名服务器,得到csdn.com权威 DNS 服务器地址,然后直接问这个权威DNS服务器,www.csdn.com的ip是什么,得到了IP地址,最后还会把这个域名和ip的对应关系存到自己本地的dns服务器上。(每次解析的时候,如果发现自己的dns服务器本身就保存了这个域名和ip的对应关系,就不需要去问根域名服务器再一步步问下去了)
ip地址是通信的逻辑地址,但是实际上我们要发送的是物理地址,因此我们还要根据ip地址去寻找mac物理地址。
2.2 如何找到对方的mac地址呢
这里涉及到两个协议:arp协议和ip协议。
首先我们会看本地arp缓存中,有没有目标ip对应的mac地址,有的话就直接装上,没有的话我们再去找。
第二,会去使用arp协议进行一个广播局域网查询,所有连接到这个局域网的设备都会被询问:你有没有这个ip地址对应的mac地址啊。如果没有就不回答,有的话就会返回一个arp包。如果全都没有,那么就会报错,需要修改网络配置了。
这里实际上我一开始不太明白,如果只能在一个局域网内部查询的话,那我们平时是怎么连接那么多网站的,后面看了具体解析才明白了,这是涉及到路由器的。
路由器是基于IP设计的三层网络设备,路由器的每个端口都有MAC地址和IP地址。
我们是知道ip地址的,我们会将这个ip地址交给路由器,路由器会帮我们判断这个ip地址在不在这个局域网内部。(这一步实际上是通过源IP对应网卡的子网掩码实现的)
如果在,那么直接对着这个局域网内部喊就可以得到mac地址了
如果不在,那么我们就明白了,你要传出去这个数据包,肯定要先走这个路由器,则你的第一个mac头,实际上是路由器的mac地址(但是这一步还是需要),路由器根据目标ip地址,决定自己从哪个端口进行发送,然后到下一个位置,这个决定过程也是需要经过判断的,判断的方式实际上就是根据每个端口的子网掩码来,子网掩码和目标ip做与运算,得到的结果如果与目标地址相同,就走这个端口,不同就继续看看下个端口能不能走。如果所有端口都不符合,那么就会走默认路由,该端口的子网掩码为0.0.0.0。端口判断完毕之后,每个端口还对应着网关,如果网关是ip地址,那么就说明还得继续转发到下一个路由器;如果网关为空,那么说明这个局域网就是我们目标ip在的位置,用arp协议对着这个局域网开始喊,找mac地址就完事了。
在这整个找mac地址的过程中,ip地址是不会变的,但是mac头部是会一直改变的,因为mac不是源头对目标的连接桥梁,而是中途所经历的所有设备两两连接的桥梁。
3 确认通信环境
这一步不是必要的,也可以直接发送,出问题再说。
确认通信环境的目的只有一个,确认这数据包能安全送到
3.1 如何确认数据包能送到?
使用ICMP协议,我们常用的ping命令就是基于这个协议工作的
在数据包的传输过程中,如果某个ip包因为某种原因,没能到达我们的目的地,那么这个具体的原因就会以ICMP包的形式返回来通知,这类出错原因包括但不限于:超时,目标不可达,重定向等。
也正因此,我们希望在发送数据包前就明确通信环境是否安全可靠,可以使用ping命令进行通信环境测试,所谓的ping命令就是提前发送ICMP包过去,看看中间会不会出问题,如果服务器收到了并正常返回,那么就说明这个通信环境是可靠的,如果出问题了,或者不正常返回,ICMP也会给我们报对应的错误信息,方便我们排查问题
4 发送数据包
现在,我们是拥有ip地址,目标端口,mac地址
4.1 如何发送数据包呢?
这个发送过程需要借助交换机来实现,交换机中存放着端口和mac地址的关系表,我们会根据我们要发送的mac地址,让交换机选择对应的端口进行发送。
当然也会存在交换机没有这个地址的情况,也就是说交换机无法判断到底要发送到哪个端口,那么只能广播这个包了,即除了源端口,其他的端口都发送一遍,只有对应的mac地址的设备才接收,其他的设备都选择忽略这个包,而只要接收一次,接收设备就会发送响应包,让交换机把这个mac地址和端口的对应关系存储在关系表中,下一次就不需要广播了。
接下来就是路由器的转发过程了,这一步在上面的找到传输目的地的mac地址部分已经说过了就不重复了。
以上是我对这个过程比较粗略的理解,主要起到一个整理自己思路的作用,如果有问题还请大家指出来,