V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
OrdinaryMan
V2EX  ›  程序员

一个关于计算机网络的疑问

  •  
  •   OrdinaryMan ·
    YangFanJack · 2023-06-29 09:40:16 +08:00 · 6123 次点击
    这是一个创建于 505 天前的主题,其中的信息可能已经有所发展或是发生改变。

    计算机发送 ip 数据包时,如何判断目的 ip 和本地 ip 是否属于同一网段?

    网上的答案是:使用本地子网掩码分别和本地 IP 和目的 IP 进行按位与运算分别得到本地网络号和目的网络号,比较网络号是否相同

    但是如果目的 ip 所在的网段子网掩码和本地的子网掩码不一样,比如: 本地 ip:192.168.1.1 本地子网掩码:255.255.255.0 目的 ip:192.168.1.193 目的子网掩码:255.255.255.192 这种情况按照上述判断方式结果是属于同一网段,然而实际上是两个不同的网段

    所以,正确答案是什么?

    56 条回复    2023-07-02 15:55:12 +08:00
    OrdinaryMan
        1
    OrdinaryMan  
    OP
       2023-06-29 09:46:11 +08:00 via Android
    求解
    seeme
        2
    seeme  
       2023-06-29 09:48:29 +08:00
    计算的时候不考虑目的 ip 的掩码吧
    OrdinaryMan
        3
    OrdinaryMan  
    OP
       2023-06-29 09:49:36 +08:00 via Android
    @seeme 那这种错误的出现怎么避免呢
    ysc3839
        4
    ysc3839  
       2023-06-29 09:54:24 +08:00 via Android
    没有“目的子网掩码”,用本地子网掩码计算后就能知道是不是在同一网段
    OrdinaryMan
        5
    OrdinaryMan  
    OP
       2023-06-29 09:57:02 +08:00
    @ysc3839 那怎么解释这种情况呢——>本地 ip:192.168.1.1 本地子网掩码:255.255.255.0 目的 ip:192.168.1.193 目的子网掩码
    jdOY
        6
    jdOY  
       2023-06-29 09:57:26 +08:00
    判断是否跨网段的方法没问题的,网络传输过程中硬件设备把这些步骤做好了而已,去看看网络工程就能大概了解
    yuanix
        7
    yuanix  
       2023-06-29 09:58:26 +08:00 via Android   ❤️ 1
    @OrdinaryMan 感觉不是错误,如果想要两台机器能通过交换机互联,那就配置成同一网段。当然也可以使用不同的掩码,进一步划分子网,
    seeme
        8
    seeme  
       2023-06-29 09:59:03 +08:00
    @OrdinaryMan #3 这不是错误阿,网络世界都是只管发包,能不能收到回包看路径上如何转发 /处理这些数据包。
    举个例子,你本地 ip192.168.1.1/24 ,通过 dns 解析到一个 ip3.3.3.3 ,这时候你通过计算网络发现不属于 192.168.1.1/24 这个网段,那么这个数据包就会查找其他符合条件的网关(大部分情况都是默认网关)进行发送。

    如果你想让你的机器正确收到回包,需要探究下 NAT 、路由相关的知识。
    arnoldxiao
        9
    arnoldxiao  
       2023-06-29 09:59:08 +08:00
    子网掩码末位 192 转换为 8 位二进制是 1100 0000 ,
    和 IP 地址进行计算,
    所以目的地网络号为 192.168.1.192 ,
    和本地的网络号 192.169.1.0 不一致,
    所以不属于同一网段
    xiaobai1213
        10
    xiaobai1213  
       2023-06-29 10:00:10 +08:00
    没有目的子网掩码这个说法 , 他只会和本机的子网掩码与一下 发现是同一网络就是同一网络了 至于下面怎么走 那是路由的事儿了。
    lifekevin
        11
    lifekevin  
       2023-06-29 10:00:34 +08:00   ❤️ 5
    只会判断目的 ip 属不属于自己的子网,不会考虑对方的子网掩码。
    你的举例中,192.168.1.1/24 可以访问 192.168.1.192/28 ,但是 192.168.1.192/28 访问不了 192.168.1.1 。
    因为 192.168.1.192 属于 192.168.1.1/24 子网,但是 192.168.1.1 不在 192.168.1.192/28 的子网中。
    adoal
        12
    adoal  
       2023-06-29 10:01:32 +08:00
    如果这两个节点在同一二层网络,把做配置的拖出去打死。
    如果在不同的二层网络,把提要求的拖出去打死。
    jiulang
        13
    jiulang  
       2023-06-29 10:03:24 +08:00
    我怎么感觉这个问题是:如何判断我的局域网的 192.168.1.192 ,和你家的局域网的 192.168.1.193 ,不在同一个网段一样。

    那么问题来了,你家的 192.168.1.192 自然不能直接连接我的 192.168.1.193 ,这个判断有什么意义呢
    killva4624
        14
    killva4624  
       2023-06-29 10:04:22 +08:00   ❤️ 5
    这个不冲突。
    - 192.168.1.1 给 192.168.1.193 发包的时候,判断目的 IP 在同一个网络。
    - 192.168.1.193 给 192.168.1.1 发包的时候,判断目的 IP 不在同一个网络。

    你用 Cisco 模拟器试试就明白了。
    Yourshell
        15
    Yourshell  
       2023-06-29 10:05:02 +08:00
    你的目标 ip 是被 nat 后的啊
    blessingsi
        16
    blessingsi  
       2023-06-29 10:05:33 +08:00   ❤️ 2
    子网掩码是网络的属性,不是某台机器的属性。路由表里面每一行都包括 网络地址,子网掩码,和对应的下一跳地址。目的 ip 和每一行中的掩码做与,看是否和这行中的网络地址匹配。如果一个目的 ip 能同时满足多行记录,那么用掩码长度最长的那个。
    goodryb
        17
    goodryb  
       2023-06-29 10:08:47 +08:00
    正确答案就是判断是否同一网络 只看目标地址和自身的网络掩码

    是 就直连
    否,查询本机路由表,根据路由表发送

    上述都是系统层面的,应用层感知不到这个过程
    raysonx
        18
    raysonx  
       2023-06-29 10:09:30 +08:00   ❤️ 1
    > 计算机发送 ip 数据包时,如何判断目的 ip 和本地 ip 是否属于同一网段?
    这个假设是错误的。发送 ip 数据包时,会通过查找路由表来决定发送的目的地,不会关心目的 ip 和本地 ip 是否属于同一网段。
    实际上你本地计算机根本不知道目的 IP 的子网掩码,比如你往 8.8.8.8 发送数据,难道 Google 还需要暴露它的网络结构给你吗?

    拿你的例子:
    本地 ip:192.168.1.1 本地子网掩码:255.255.255.0
    目的 ip:192.168.1.193 目的子网掩码:255.255.255.192

    本机会生成路由表:
    0.0.0.0/0 via 网关 A dev 网卡 A
    local 192.168.1.1/32
    192.168.1.0/24 dev 网卡 B

    在给 192.168.1.193 发送数据时,匹配到第 3 条路由,直接从“网卡 A”送出(目的 mac 地址为 192.168.1.193 的 mac 地址)。
    在给 8.8.8.8 发送数据时,匹配到第 1 条路由,从“网卡 B”经“网关 A”送出(目的 mac 地址为网关 A 的 mac 地址)。
    JayZXu
        19
    JayZXu  
       2023-06-29 10:11:21 +08:00   ❤️ 1
    发包路径根据路由表来寻址。
    路由表的建立是比较复杂的过程,不是简单看子网掩码能决定的。

    如果只是做题,用子网掩码算出内网 IP 范围就行。
    你列举的例子,在实际情况下,不可能通过 192.168.1.193 跨网段请求。
    raysonx
        20
    raysonx  
       2023-06-29 10:11:46 +08:00
    纠正上述一处错误:

    在给 192.168.1.193 发送数据时,匹配到第 3 条路由,直接从“网卡 B”送出(目的 mac 地址为 192.168.1.193 的 mac 地址)。
    在给 8.8.8.8 发送数据时,匹配到第 1 条路由,从“网卡 A ”经“网关 A”送出(目的 mac 地址为网关 A 的 mac 地址)。
    libook
        21
    libook  
       2023-06-29 10:13:35 +08:00
    计算机在与目标 IP 通信前,会先查看自己接入了哪几个网段,然后看目标 IP 在自己的哪个网段里。如果自己同时接入的多个网段有重合,而目标 IP 恰好在这个重合范围内,有可能计算机会使用错误的网络接口尝试与目标 IP 通信。
    如果目标 IP 不在自己接入的任何网段,且自己可以连接到至少一个网关,那么将会尝试让网关帮忙找到路由。

    这个过程不会获得到目标的子网信息,仅靠一个目标 IP 和自己的接入的网络信息来完成。
    raysonx
        22
    raysonx  
       2023-06-29 10:16:58 +08:00
    上述所有的回答中,只有 @blessingsi 和 @JayZXu 的回答是正确的,其他的要么错误,要么没回答到点子上。

    发包时会匹配路由表,而不是看是否和本机是否同一子网。假设你本地的路由表有很多条目,会拿目的地址与每一条路由条目匹配(实际存在二分查找),找到最长前缀那一条,再决定下一步的动作。
    raysonx
        23
    raysonx  
       2023-06-29 10:22:02 +08:00
    驳“如果自己同时接入的多个网段有重合,而目标 IP 恰好在这个重合范围内,有可能计算机会使用错误的网络接口尝试与目标 IP 通信。”
    假如本地同时有两张网卡,分别配置为:
    eth1: 192.168.1.100/24
    eth2: 192.168.1.101/23
    这时候,系统会生成路由表:
    local 192.168.1.100
    local 192.168.1.101
    192.168.1.0/24 dev eth1
    192.168.0.0/23 dev eth2

    如果往 192.168.0.1 发包,只会匹配到 192.168.0.0/23 dev eth2 ,所以会从 eth2 发出;
    如果往 192.168.1.1 发包,会匹配前缀最长的 192.168.1.0/24 dev eth1 ,所以会从 eth1 发出。
    8355
        24
    8355  
       2023-06-29 10:22:26 +08:00
    举个最简单的例子吧。。。
    假设你局域网的 ip 地址是 1.1.1.1 你 ping 1.1.1.2
    假设局域网有 1.1.1.2 那么 ping 的是局域网内的 ip
    没有的该地址 ping 的就是外网的 1.1.1.2

    判断是否同一网段不是发出方决定的
    Vraw5
        25
    Vraw5  
       2023-06-29 10:24:03 +08:00
    对方的掩码你不知道的呀,就像你要给 8.8.8.8 发数据,你不知道它的掩码是啥,本地只知道匹配到要走网关。

    本地只要判断对方 ip 和本地是不是同段,然后去匹配相应的路由。

    通过路由没过去或者没回来,网络不通就要排查是没过去还是没回来,没回来是因为啥。

    这个过程已经走过“判断目的 ip 和本地 Ip 是否同段”这步了,且和目的 ip 的掩码无关。
    wheat0r
        26
    wheat0r  
       2023-06-29 10:47:41 +08:00   ❤️ 1
    你按照你的子网掩码往出发,对方按照他的子网掩码回包。
    leonshaw
        27
    leonshaw  
       2023-06-29 10:52:20 +08:00
    查路由,看下一跳是接口 /二层邻居还是 IP 地址。
    配 IP 子网掩码的本质也是生成了一条下一跳指向接口的路由。
    OrdinaryMan
        28
    OrdinaryMan  
    OP
       2023-06-29 11:03:20 +08:00 via Android
    @killva4624 豁然开朗
    OrdinaryMan
        29
    OrdinaryMan  
    OP
       2023-06-29 11:04:25 +08:00 via Android
    @raysonx 我的理解是第一步是判断是否同网段,不同网段才会查路由表
    OrdinaryMan
        30
    OrdinaryMan  
    OP
       2023-06-29 11:06:23 +08:00 via Android
    @wheat0r OK ,明白了
    OrdinaryMan
        31
    OrdinaryMan  
    OP
       2023-06-29 11:14:02 +08:00 via Android
    路由表中通常只保存不同网段的路由信息,用于选择转发数据包的下一跃点路由器。
    本地网段内的 IP 地址可以通过 ARP 协议直接解析为 MAC 地址,用于直接发送数据包。路由表保存的路由条目通常包含下一跃点的 IP 地址,用于向指定路由器发送数据包。
    如果向路由表中添加同一网段内所有主机的路由,会极大增加路由表的体积,降低查找效率。这没有实际意义
    OrdinaryMan
        32
    OrdinaryMan  
    OP
       2023-06-29 11:20:21 +08:00
    @killva4624 192.168.1.1 给 192.168.1.193 发包的时候,判断目的 IP 在同一个网络,就直接用 arp 协议查 mac ,但是查不到,这个时候就需要查路由表了吧?
    NeoZephyr
        33
    NeoZephyr  
       2023-06-29 11:48:15 +08:00
    是否属于同一网段,是一个台机器自己主观的判断。一般来说,掩码一样的话,那判断是一致的。但如果掩码不一致的话,是否属于同一网段,也是得到的答案不一致的
    ketor
        34
    ketor  
       2023-06-29 11:56:04 +08:00
    找了个现在用的服务器上的路由信息
    ip route 的输出如下:
    default via 192.20.8.88 dev eth1 proto static metric 10
    default via 192.20.1.1 dev eth1 proto static metric 100
    192.17.0.0/16 dev docker0 proto kernel scope link src 192.17.0.1
    192.20.0.0/17 dev eth1 proto kernel scope link src 192.20.31.12 metric 100
    junwind
        35
    junwind  
       2023-06-29 12:00:47 +08:00
    你本机发送,是先到你的路由器的,本机并不需要关心目的地 ip ,由路由器负责层层转发,能不能转发到,由路由器的映射表决定。
    ketor
        36
    ketor  
       2023-06-29 12:06:04 +08:00
    OP 直接理解为本地发包的时候就是从路由表里进行规则匹配就对了,匹配到哪一条路由规则,就按照规则发包,规则里指定了发到哪个网卡设备,metric 信息等等。

    比如说本地有 eth1 ,还有个 docker0 ,如果目的 IP 是 192.17.0.2 ,那么会匹配到 192.17.0.0/16 这个规则,会发送到 docker0 这个网卡上,这里就直接是以太网过去了。

    如果目的 IP 是 1.1.1.1 ,那么最终会匹配到 default 规则,default 有 2 条,metric 较小的优先级更高,所以会把 IP 包发给 192.20.8.88 这个 IP 地址,走 eth1 网卡。192.20.8.88 是否具备 ip forward 的能力是它的问题,它会把这个包转发给谁又是根据它自己的路由表来确定的。

    整个网络的交互就是这样的,一个 IP 报文就是一个节点一个节点这么转发的,每个节点都根据自己本机配置的路由表进行转发给下一个目的。 对端 IP 回包的时候,也是一样的流程。

    实际上的网络比这个过程要多很多细节,有各种路由交换协议来解决路由传播的问题; 在小的网络里面也有 VLAN 、VXLAN ,各种 GRE 隧道之类的。即使是在本机,路由表也不一定是上面展示的这么简单,还要看策略路由是否有配置,iptables 是否有规则表会在发包和收包的过程中做数据的转换,是 prerouting 还是 postrouting 对包的流向影响也不同。

    要想有一个比较全面的理解,可能还是需要稍微系统性的了解一下计算机网络的知识才能有更深入全面的认识。
    希望可以帮到 OP 。
    julyclyde
        37
    julyclyde  
       2023-06-29 12:29:50 +08:00
    以发送方的掩码判断
    掩码仅具有本地意义(也就是说别人的掩码只对别人自己有效,对我没什么影响)
    julyclyde
        38
    julyclyde  
       2023-06-29 12:32:14 +08:00
    @OrdinaryMan 其实计算掩码是查路由表的一个步骤。不存在“不同网段才”这种说法
    无论是否在同一个网段,都得 arp 查 mac ,无非是查目标地址还是查网关的 mac 的区别而已
    txydhr
        39
    txydhr  
       2023-06-29 12:51:46 +08:00 via iPhone   ❤️ 1
    @OrdinaryMan 不查路由表,在局域网内广播寻找
    dcsuibian
        40
    dcsuibian  
       2023-06-29 13:14:55 +08:00 via Android
    确实都属于 192.168.1.0/24 啊
    la2la
        41
    la2la  
       2023-06-29 13:42:59 +08:00
    子网掩码不同应该是跨网段了,走路由
    folnet
        42
    folnet  
       2023-06-29 13:44:26 +08:00
    只看本端掩码, 可以看一下 wireshark 网络分析就这么简单
    leonshaw
        43
    leonshaw  
       2023-06-29 13:58:23 +08:00
    @OrdinaryMan #32 不是,没有所谓判断 IP 在同一个网络的过程,都要先查路由表,根据结果再查二层邻居。
    可以试一下:
    1. IP 配成 192.168.1.1/24 ,删除 192.168.1.0/24 的路由
    2. IP 配成 192.168.1.1/32 ,添加 192.168.1.0/24 的直连路由
    yuchenr
        44
    yuchenr  
       2023-06-29 14:03:07 +08:00
    本地 ip:192.168.1.1 本地子网掩码:255.255.255.0
    目的 ip:192.168.1.193 目的子网掩码:255.255.255.192

    192.168.1.1 访问 192.168.1.193 属于直连,不需要路由
    192.168.1.193 访问 192.168.1.1 需要路由
    lostc
        45
    lostc  
       2023-06-29 14:10:11 +08:00
    计算机不管这些,管这些的是网关
    Seayon
        46
    Seayon  
       2023-06-29 16:26:48 +08:00
    chatgpt4:

    您提出了一个很好的问题。实际上,计算机在发送 IP 数据包时,并不知道目标 IP 的子网掩码。计算机只知道自己的 IP 地址和子网掩码,以及默认网关的 IP 地址。因此,在发送 IP 数据包时,计算机无法判断目标 IP 是否真正位于同一网段。

    在这种情况下,计算机会先利用自己的子网掩码和 IP 地址来判断目标 IP 是否位于本地网络。如果目标 IP 与本地网络匹配,计算机将直接将数据包发送至目标 IP 。如果不匹配,计算机会将数据包发送至默认网关,然后由路由器根据路由表来判断数据包的最佳路径。

    因此,关于您提到的这个问题,实际上计算机并不需要知道目标 IP 的子网掩码。计算机只需要根据自己的子网掩码来判断目标 IP 是否位于本地网络,然后将数据包发送至相应的位置。在路由过程中,目标 IP 的子网掩码将被正确处理。
    raysonx
        47
    raysonx  
       2023-06-29 16:27:18 +08:00
    @OrdinaryMan
    > 我的理解是第一步是判断是否同网段,不同网段才会查路由表
    你这理解完全是错的,而且完全没看我的回复。这楼上绝大多数人的回答都是错的,可见大多数程序员对网络只是一知半解,回答全凭臆测。

    所谓掩码只是设定本机路由表的一种快捷方式。发包时,机器只是遵循路由表的设置,不会关心网段相同还是不相同的问题。不管同不同网段,如果手动加上路由条目,系统也会按照路由条目的指示来动作。
    raysonx
        48
    raysonx  
       2023-06-29 16:33:36 +08:00   ❤️ 1
    再举一个例子,假如本机 IP 是 192.168.1.100/24 ,外加一条 192.168.1.101/32 via 192.168.1.254 的静态路由,则本机向 192.168.1.101 发包时,就会发给 192.168.1.254 这个网关。

    这个例子可以推翻楼上所有所谓先判断是否和本地同网段的论述,即使是 gpt 的回答也是错的。发包时发给谁完全遵循路由表,不存在提前判断是否同一网段这个步骤。
    raysonx
        49
    raysonx  
       2023-06-29 16:34:36 +08:00
    我已经不想在这个问题上再做过多解释了,建议买本计算机网络的专业书看看。
    hezhile
        50
    hezhile  
       2023-06-29 17:29:52 +08:00
    多看书。。。
    bomb77
        51
    bomb77  
       2023-06-29 18:18:51 +08:00
    @raysonx #48 哈哈哈,好多人对路由表视若罔闻
    deorth
        52
    deorth  
       2023-06-29 18:47:29 +08:00 via Android
    简单来说,如果你在自己不擅长的领域提问题,通常就会显得很蠢。
    怎样才算擅长呢?我也不知道,所以我通常不提问题。
    xiaolang
        53
    xiaolang  
       2023-06-29 20:19:37 +08:00
    配置了网关的话可以 Ping 通,没配置的话 Ping 不通。
    joshu
        54
    joshu  
       2023-06-30 10:44:50 +08:00
    是否为同一网段,本质在于本侧是否认为对侧是 on-link ,也就是可以通过 arp 包获得对端的地址
    首先你这样的配置,必然导致某一小段路由不互通,或存在其它连接性问题,又或者某些 host 是不可达的
    本地 IP 肯定是认为对端是 on-link 的,因此会在局域网直接访问对方
    反过来,对端在回包的时候的,是不能直接连接到本地 IP 的,必须要通过你所设置的网关转发流量,除非目的 IP 为本地 IP 设置了 onlink 路由
    jiankaikey
        55
    jiankaikey  
       2023-06-30 11:24:56 +08:00
    但是如果目的 ip 所在的网段子网掩码和本地的子网掩码不一样,比如: 本地 ip:192.168.1.1 本地子网掩码:255.255.255.0 目的 ip:192.168.1.193 目的子网掩码:255.255.255.192 这种情况按照上述判断方式结果是属于同一网段,然而实际上是两个不同的网段

    这个题我会,这堂课我听了,老师说你一定要记得一个问题,网络是有去有回的。去的是时候 1.1 认为 1.193 是同一个网段直接广播数据可以到 1.193 ,回的时候 1.193 认为 1.1 不是同一个网段所以就会先丢给网关,那么如果没网关没有默认路由那它就不知道往哪发了,只能憋着。

    A 192.168.1.1 和 192.168.1.193 分别与 255.255.255.0 做与运算结果相同所以在同一网段
    B 192.168.1.1 和 192.168.1.193 分别与 255.255.255.192 做与运算结果不同所以不在同一网段
    OrdinaryMan
        56
    OrdinaryMan  
    OP
       2023-07-02 15:55:12 +08:00 via Android
    @deorth 蠢就蠢呗,不过我觉得这只是暂时的。如果我不提问题我可能会一直蠢下去。学习嘛,放低姿态不丢人
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2484 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 15:54 · PVG 23:54 · LAX 07:54 · JFK 10:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.