1 前言
我们对于计算机网络的学习通常是按照网络结构的分层结构逐层进行学习的,各层之间的协议都是分开讲解的,学完可能某个协议听明白了,但这个协议在实际网络传输中起到了什么作用可能感觉还是云里雾里。
本篇根据网络五层结构(应用层、传输层、网络层、数据链路层、物理层)说下数据是如何从一台计算机的应用程序通过网络一步步传到远程计算机目标应用程序的。(每一层实际的处理要比本篇叙述要复杂得多,本文中只涉及最核心的流程)
2 数据在网络分层结构间传递
用最笼统的方式来说,数据在应用层产生,逐层向下传递处理,最后经过物理层来到互联网中传递到对方计算机。这些层在计算机中都有相应的负责角色。

现在我们来看看在每一层计算机都做了哪些事。
2.1 应用层
位于应用层的角色就是我们使用的应用程序,我们要发送或接收的数据最初在这一层产生。应用程序产生数据后,交由操作系统进行发送,接着进入下一层传输层。
2.2 传输层
在操作系统中每个应用程序都要有一个(或多个)的端口号,用于计算机在处理网络请求时区分不同的应用程序。比如下图中App1占用了3000端口,App2占用了4000端口。
当远程计算机想请求App3时,就要通过IP和端口来访问,图中的例子就是192.168.1.10:5000。

操作系统在传输层中会为应用层传下来的data添加上一个头部,包含源端口号和目的端口号:

这样当目标计算机收到请求时,操作系统就知道了要分配给哪一个应用程序了,同时也知道了来源端口号方便回复。传输层包装后的数据叫做数据报,接着继续传递给网络层进行处理。
2.3 网络层
在网络层会再给数据报加一个头部,包含了源IP地址和目标IP地址:

现在整个数据被叫做数据包,接着传递给数据链路层。
2.4 数据链路层
在数据链路层,会给数据添加上目标计算机网卡的MAC地址以及自己的MAC地址。MAC地址是一个硬件地址,是硬件设备的标识,而且不会重复。
添加MAC地址后,还要在数据两端加上定界符,可以判断出一个帧的起始位置和结束位置,还会加入一些用于校验的数据:

这一步叫做封装成帧,之后网卡就会把帧推送到物理层,也就是网线上进行传输了。
其他网络设备
网络中不只有计算机结点,还有两类重要的设备,分别是三层路由器和两层交换机,都负责转发报文到对应的网络线路上。至于为什么分别是三层和两层,下面这张图就很明显了:

路由器解析到获取IP地址根据路由表转发,交换机根据MAC地址进行转发。
2.5 接收处理
当目标计算机收到了由计算机1上的App1发送的数据后,会执行一遍上述过程的逆过程,也就是一层层把对应层添加的头部尾部给去掉,从物理层逐层传递给应用层中的应用程序。
在这个过程中,每一层会对自己对应层的头尾部信息进行验证。比如数据链路层会验证帧的目标MAC地址是不是自己,不是就会丢弃收到的数据。
总结
整个过程可以形象地理解为发送快递,发件人准备好商品,一层层包装,然后交给快递公司发货前,贴上地址(IP)和收件人(MAC),之后发送到地方后,交给收件人再撕下标签拆开包装获得商品。
3 网络寻址过程
在数据封装到数据链路层之前,我们自己是一定知道对方的IP和端口号的,因为我们发送请求或者建立连接靠的就是IP加端口。
比如你访问百度的服务器,浏览器会请求www.baidu.com,这时浏览器通过DNS进行域名解析,解析后得到了www.baidu.com这个域名对应的ip地址,然后用https请求默认端口就是443。
到这都很顺利,然后来到数据链路层就出现问题了,目标计算机网卡的硬件MAC地址怎么获取呢? 这时候就需要ARP协议了。
3.1 ARP协议
ARP(Address Resolution Protocol,地址解析协议)是用来将IP地址解析为MAC地址的协议。首先计算机先查看自己的ARP缓存表是否记录过目标IP对应的MAC地址,如果没有就需要通过在网络来广播ARP请求询问。
3.1.1 目标在同一内网
交换机:下面图中连接四个计算机的用于表示交换机,用于把各个计算机连接在一起,通过连接端口和MAC地址绑定进行交换,通过广播和记录经过报文实现对计算机透明。
以计算机1请求10.0.0.2的MAC地址为例。首先计算机1发现ARP表中没有对应的MAC地址,发送一个ARP广播请求,包含了自己的MAC和IP以及目标IP和空的MAC地址:

之后计算机2、3、4都会收到这个ARP请求,但是只有计算机3的IP是请求中的目标IP,其他两个台计算机会直接丢弃这个ARP请求:

然后计算机3会把计算机1的IP和MAC加入ARP缓存表,并回复给计算机1一个ARP响应,这次只会发给计算机1而不会广播:

当计算机1收到ARP响应后会把计算机3的IP和MAC加入到自己的ARP缓存表:

至此计算机1就获得了IP为10.0.0.1对应的MAC地址MAC2。
3.1.2 目标在其他网段
路由器:连接局域网内的主机,可以作为网关使主机连接到其他局域网。有两组IP和MAC地址分别对内网和外网。
上面的步骤解决了同一子网下的ARP请求过程,那如果目标主机不在一个局域网内呢? 如下图所示:

(接下来的图示中只保留通信的两个计算机)
(一)无法访问的情况
首先看这种情况,计算机1要向计算机2发送数据:

图中两个主机的IP是由各自网关路由器分配的,所以有可能是相同的内网IP地址。在这种连接下,默认情况计算机1是无法访问到计算机2的。
因为即使要访问,计算机1的目标IP地址是需要写成路由器2通过NAT为计算机2映射出来的公网地址IP3,但端口号又无法指定。
因为这个映射出来的端口号是通过NAT,根据在计算机2中的某个进程请求外网时在出网关前数据包内的源IP地址,比如192.168.1.10:5000,到达路由器2后为其映射出来的一个端口,比如IP3:6000。到时候有数据发往IP3:6000就会由路由器转发给192.168.1.10:5000。
这个映射出来的地址就已经带有端口了,我们就无法再添加端口指定到计算机2中的某个进程了。经常玩Steam上联机游戏的朋友肯定会发现即使有些游戏支持IP连接,在这种NAT环境下也是不能用的。
解决办法可以使用端口映射或者内网穿透,但其实只开放了设定的端口,还是不能自由发送到任意端口,本文不再详述。
(二)跨局域网时的ARP协议执行流程
首先,ARP协议是局域网范围的协议,如果在封装成帧的时候发现目标IP不在同一局域网内(用子网掩码就能判断了),那么就会把目标MAC地址写成网关路由器的MAC地址。
网关路由器与发送方计算机位于同一局域网,如果ARP缓存表中没有网关的MAC地址,就按3.1.1中的步骤来获取。
现在我们有这样的网络,计算机1要发送给服务器:

其中路由器1是NAT路由器,路由器2和3是在公网中传播过程中要经过的路由器。首先计算机1要发送帧(图中只画了MAC和IP),现在的帧如图所示:

因为服务器与计算机1不处于同一网段,所以会发送给网关路由器1。这时源IP和目的IP是192.168.1.10和10.0.0.10。到达路由器1之后,路由器会通过NAT给这个帧的发送程序映射出一个公网IP和端口,并替换原来的源IP地址和端口为映射后的公网IP和端口。之后继续使用ARP协议找到下一跳设备的MAC替换目标MAC,用自己的MAC地址替换源MAC:

之后的步骤同上,但是源IP因为已经通过NAT获得了公网IP,不需要再进行替换了,但是MAC在每一跳都需要替换:


然后服务器收到了帧。
之后服务器如果要进行响应,就对IP2和NAT映射出的端口发送信息。等到路由器收到响应帧,因为之前已经建立过端口和计算机1IP地址和某个进程端口的映射,再把帧当中的目标IP地址替换为192.168.1.10,端口替换为真实请求应用的端口,再把帧转发给计算机1的那个程序。
现在又有个问题,路由器是怎么知道帧应该从哪个口出去发往下一个路由器的? 总不能每次转发时都广播给当前网络的所有设备吧?这时就要用到设备内的路由表了。
3.2 路径选择协议
路由表中记录了目标IP地址对应的当前路由器的下一跳对应的输出接口。这样当路由器转发数据帧的时候,向上层拆包到网络层获取了目标IP后,查一下对应的输出接口,直接把帧再按上面的过程封装成帧从那个接口转发出去就可以了。
路由表中的表项内容包括:
destination:目的地址,用来标识IP包的目的地址或者目的网络。
mask:网络掩码,与目的地址一起标识目的主机或者路由器所在的网段的地址。
pre:标识路由加入IP路由表的优先级。可能到达一个目的地有多条路由,但是优先级的存在让他们先选择优先级高的路由进行利用。
cost:路由开销,当到达一个目的地的多个路由优先级相同时,路由开销最小的将成为最优路由。
interface:输出接口,说明IP包将从该路由器哪个接口转发。 nexthop:下一跳IP地址,说明IP包所经过的下一个路由器。(百度百科)
那么设备内的路由表是怎么维护的呢?
主要通过路由选择协议,主要是RIP协议和OSPF协议。中心思想就是路由器之间彼此共享自己的全部路由信息。
RIP是按固定时间间隔与相邻的路由器进行交换,OSPF是链路状态发生变化时通过洪泛(所有结点收到消息后会发送给除了发送方的所有相邻方)。
在每次信息交换中,路由器会比较收到的路由信息和自己当前的路由信息,留下前往某个IP地址需要的代价最小的。
最终经过多次更新,使每一个路由器都收敛于一个相同的全网路由信息,持有了送往当前网络中所有IP地址的路由信息。
4 总结
整个过程就是数据从应用层产生,向下逐层封装后传输到网线上,每一次传递需要知道当前网络内的下一跳设备MAC地址并更改帧的目的设备MAC地址,其中目的IP始终保持目标设备所在的公网IP。
如果源IP来自内网,目标IP开始为网关,进入到公网时需要被网关替换为自己的IP和映射的端口。
4014

被折叠的 条评论
为什么被折叠?



