网络模型被OSI分成七层,TCP/IP协议大致对应了2、3、4、7层,分别是数据链路层、网络层、传输层、应用层,IP协议处于网络层上,它的工作原理说白了并不复杂:
  1. 整个互联网上所有的机器都有唯一一个IP地址对应。这并没有什么稀奇的,MAC地址也是唯一的,稀奇的在后面
  2. 机器的IP地址按照连接顺序进行了一定程度的分组,这样一个连续的IP段大致都在相同的路线上,这样路由器寻找特定IP地址的时候就方便多了,把整个地址空间分成若干个可能重叠的大段,每个大段一般这样表示:A.B.C.D/n,表示32位IP地址的前n位与A.B.C.D的前n位相同。比如192.168.1.0/24,所有前24位与192.168.1.0相同的都是这个网段的IP,由于IP地址8位一分组,24位就是前三段,也就是192.168.1.x。符合规范的这段连续的IP段就叫做一个子网。这种子网的表示方法叫做CIDR。
  3. 这种表示方法对人来说比较直观,但是计算机有另一种更快速的计算方法,对于A.B.C.D/n,我们构造一个前n位都是1、后面其他位都是0的IP地址,这个32位IP地址和A.B.C.D按位与的结果,就是前n位与A.B.C.D相同而后面其他位都是0的IP地址;如果这个32位IP地址和另一个IP地址与的结果,刚好与A.B.C.D与的结果相等,就说明这个IP地址和A.B.C.D的前n位相等,就说明新IP地址在CIDR范围内。我们把前n位都是1、后面其他位是0的地址也用IP地址的形式表示出来,那么192.168.1.0/24对应的就是255.255.255.0,这个就叫做子网掩码,掩码也就是mask,mask在计算机用语当中表示按位与的操作数,用来从目标数中取出特定的二进制位。也就是说IP+子网掩码是CIDR的另一种表示形式。

对于任意一台计算机或者路由器来说,它首先会有一些本地的链路,这些链路的IP地址都在各自特定的CIDR当中,这个子网叫做链路子网,链路子网中的IP地址都可以通过链路层协议直接访问,具体的访问方法与IP协议无关,在以太网当中是靠ARP,但是如果是WLAN,或者令牌环网,或者PPPoE,又会有所不同。比如子网是192.168.1.0/24,那么范围内所有IP地址都会直接调用链路层协议访问。表现在路由表中,就是这样一项:

192.168.1.0/24 -> link local, ifindex = XXX

即“192.168.1.0/24范围的IP通过XXX网卡的链路层协议直接访问”

如果还有其他链路,也会有相应的表项,比如说还有一个网卡上面的链路子网是111.222.1.0/24,那么就有另一项:

111.222.1.0/24 -> link local, ifindex = YYY

特别的,每个网卡上都会有一个IP地址,是本机的IP地址。当数据包发到这个IP地址的时候,设备就会正确理解“这个数据包是发给我自己的”,否则会理解为“这个数据包需要我代为转发”。这些本机的IP地址一定在链路层子网当中,比如说192.168.1.0/24中本机的IP地址是192.168.1.1,111.222.1.0/24中的IP地址是111.222.1.15,那么就有两个表项:

192.168.1.1/32 -> local

111.222.1.15/32 -> local

到local表示交给本机的更高层的协议栈,比如TCP/UDP去处理。否则会转发到其他机器。

我们注意到这些表项和刚才的表项有重叠的部分,比如说192.168.1.1/32其实包含在192.168.1.0/24里面。路由表的不同表项有不同的优先级,子网越小的越优先,也就是后面n越大的越优先,这样192.168.1.1/32就比192.168.1.0/24优先。

除了这些IP地址以外,其他的IP地址显然是无法直接访问的,需要由其他设备进行转发。不同网段的IP地址可能需要不同的设备进行转发。我们必须在路由表当中记住某段IP具体由哪个设备转发,记录的方法是记住需要转发的IP段CIDR,和需要发往的设备的IP地址,像这样:

100.101.1.0/24 -> via 192.168.1.17

这个via后面的地址,192.168.1.17,这个设备有进一步将数据包转发到目的网段的能力,比如说上面有一个链路层子网就是100.101.1.0/24,或者有另一条路由信息表明这个网段应该进一步发给其他的某个设备。这个设备在IP协议当中就叫做Gateway(网关),因为所有发到目的网段的流量都会从这个设备上经过,这个设备像个门一样,把两个网段连接了起来。

大多数情况下,这个IP地址位于某个链路层子网中,这样本机可以直接通过链路层协议将IP报文发送到网关。一部分设备(主要是硬件路由器)支持递归的路由表配置,这个时候网关地址可以不是本地链路层子网中的地址,当需要将IP报文发送到这个网关时,设备会递归查找网关的路由信息,直到查找到可以直接发送的地址为止。

互联网上的网段太多了,而且天天都在变,我们不可能给每个设备都配上互联网上所有的网段。幸好,对于大部分设备来说,除了特定的少数几个网段以外,大部分IP地址都有相同的网关,于是我们可以通过配置一个包含整个IP空间的CIDR来指定大部分IP地址的共同的网关:

0.0.0.0/0 -> via 111.222.1.254

由于前面说的原则,子网越小越优先,这条规则的优先度最低,而且能匹配所有的IP地址,因此可以理解为无法匹配到其他子网网段时使用的默认规则,因此这个网关一般叫做默认网关。

一个设备可能有多个网关,但是一般最多只有一个默认网关(不考虑等价路由、策略路由等复杂的情况)。也有可能没有默认网关,比如说骨干网上的路由器通过BGP协议交换路由信息,一般路由表就由非常多的CIDR组成,这些CIDR合起来能覆盖互联网上所有的公网IP。

最后说下链路层地址与IP地址。许多链路层协议也有自己的地址,一般是MAC地址,比如最常用的以太网。链路层地址在链路层协议中使用,表明这个链路层报文会被发给谁;而IP地址在IP层协议中使用,表明这个报文最终要发给谁。可以分为两种情况:

1. 直接通过链路层发送:

链路层地址: (源MAC地址) (目的MAC地址)

IP地址: (源IP地址) (目的IP地址)

2. 经过网关转发

从本机出发发往网关时,链路层的目的是网关而IP层的目的不是网关:

链路层地址: (本机源MAC地址) (网关MAC地址)

IP地址: (本机IP地址) (目的IP地址)

网关转发到其他网关:

链路层地址: (网关MAC地址) (下一跳网关MAC地址)

IP地址: (本机IP地址) (目的IP地址)

最后一个网关转发到目标:

链路层地址: (最后一个网关MAC地址) (目的MAC地址)

IP地址: (本机IP地址) (目的IP地址)

在转发过程中,IP报文的源和目的保持不变,链路层地址则只和这一跳的双方有关,甚至如果中间经过了不一样的链路层,还会更换二层数据包的格式。

作者:灵剑
链接:https://www.zhihu.com/question/20717354/answer/105670397
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

ip啊的更多相关文章

  1. Tcp/ip 报文解析

    在编写网络程序时,常使用TCP协议.那么一个tcp包到底由哪些东西构成的呢?其实一个TCP包,首先需要通过IP协议承载,而IP报文,又需要通过以太网传送.下面我们来看看几种协议头的构成 一 .Ethe ...

  2. 网站定位之---根据IP获得区域

    记得以前做一个培训机构网站时候需要定位,那时候用的搜狐的api,不是很精准. demo:https://github.com/dunitian/LoTCodeBase/tree/master/NetC ...

  3. 通过 floating IP 访问 VIP - 每天5分钟玩转 OpenStack(126)

    前面我们是直接用 curl 测试 VIP,在更为真实的场景中通常会使用 floating IP 访问 VIP. 下面我们给 VIP 关联一个 floating IP,再进行测试. 访问 Project ...

  4. PHP获取客户端IP

    /** * 获取客户端IP */ function getClientIp() { $ip = 'unknown'; $unknown = 'unknown'; if (isset($_SERVER[ ...

  5. 获取 dhcp IP 过程分析 - 每天5分钟玩转 OpenStack(91)

    前面我们已经讨论了 DHCP agent 的配置以及 namespace 如何隔离 dnsmasq 服务,本节将以 cirros-vm1 为例分析获取 DHCP IP 的详细过程. 在创建 insta ...

  6. Java获取本机的IP与MAC地址

    有些机器有许多虚拟的网卡,获取IP地址时会出现一些意外,所以需要一些验证: // 获取mac地址 public static String getMacAddress() { try { Enumer ...

  7. 根据ip判断返回城市名称查询当地天气

    <?phpheader("content-type:text/html;charset=utf-8");date_default_timezone_set("Asi ...

  8. TCP/IP基础

    TCP/IP 是用于因特网 (Internet) 的通信协议. 计算机通信协议是对那些计算机必须遵守以便彼此通信的规则的描述. 什么是 TCP/IP? TCP/IP 是供已连接因特网的计算机进行通信的 ...

  9. CentOS:ECDSA host key "ip地址" for has changed and you have requested strict checking(转)

    原文地址:http://blog.csdn.net/ausboyue/article/details/52775281 Linux SSH命令错误:ECDSA host key "ip地址& ...

  10. TCP/IP之TCP_NODELAY与TCP_CORK

    TCP/IP之Nagle算法与40ms延迟提到了Nagle 算法.这样虽然提高了网络吞吐量,但是实时性却降低了,在一些交互性很强的应用程序来说是不允许的,使用TCP_NODELAY选项可以禁止Nagl ...

随机推荐

  1. kali linux常用软件配置记录

    首先膜一波,认真细致,简明有效. 感谢原博主的分享,留作参考. https://www.cnblogs.com/youfang/p/5272746.html

  2. 新增async

    import asyncio from threading import Thread import time now = lambda: time.time() print('start',now( ...

  3. 登陆 全站 user

    TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join( ...

  4. OL6.3 设置本地yum源

    仅在 Oracle Linux Server release 6.3 上测试 PS:Oracle Linux Server release 6.3仅用于测试,不能用于商业用途 [root@oracle ...

  5. 用Java实现MVPtree——MVPtree点集内去重以及衍生出来的多维向量Hash问题

    上次完成了MVPtree之后,客户又提出了MVPtree点集元素重复的问题,希望我将元素去重. 集合去重哪家强?java.util找HashSet!如果不计较元素顺序,放进去基本就没有重复元素了. 只 ...

  6. JAVA的内存模型及结构

    所有的Java开发人员可能会遇到这样的困惑?我该为堆内存设置多大空间呢?OutOfMemoryError的异常到底涉及到运行时数据的哪块区域?该怎么解决呢? Java内存模型 Java内存模型在JVM ...

  7. 选择排序法、冒泡排序法、插入排序法、系统提供的底层sort方法排序之毫秒级比较

    我的代码: package PlaneGame;/** * 选择排序法.冒泡排序法.插入排序法.系统提供的底层sort方法排序之毫秒级比较 * @author Administrator */impo ...

  8. topcoder srm 706 div1

    1.给定一个迷宫,点号表示不可行,井号表示可行.现在可以改变其中的一些井号的位置.问最少改变多少个井号可以使得从左上角到右下角存在路径. 思路:设高为$n$,宽为$m$,若井号的个数$S$小于$n+m ...

  9. git使用操作

    git config --system --unset credential.helper 重置git

  10. Ubuntu18.04 安装搜狗输入法后无法启动的问题

    ibus 改选成fcitx后搜狗输入法照样没出来. 这里需要im-config 没有的话需要安装: sudo apt install im-config 然后在Terminal中执行 im-confi ...