面试官:断网了,还能 ping 通 127.0.0.1 吗?

2023-11-11

女神爱不爱你,你问她,她可能不会告诉你。

网通不通,你 ping 一下就知道了。

可能看到标题,你就知道答案了,但是你了解背后的原因吗?

那如果把 127.0.0.1 换成 0.0.0.0localhost 会怎么样呢?你知道这几个IP有什么区别吗?

以前面试的时候就遇到过这个问题,大家看个动图了解下面试官和我当时的场景,求当时我的心里阴影面积。

话不多说,我们直接开车。

拔掉网线,断网。

断开wifi

网线一拔,恩怨去了

然后在控制台输入ping 127.0.0.1

$ ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.080 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.093 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.074 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.079 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.079 ms
^C
--- 127.0.0.1 ping statistics ---
5 packets transmitted, 5 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.074/0.081/0.093/0.006 ms

说明,拔了网线,ping 127.0.0.1  是能ping通的

其实这篇文章看到这里,标题前半个问题已经被回答了。但是我们可以再想深一点。

为什么断网了还能 ping127.0.0.1 呢?

这能说明你不用交网费就能上网吗?

不能。

首先我们需要进入基础科普环节。

不懂的同学看了就懂了,懂的看了就当查漏补缺吧。

什么是127.0.0.1

首先,这是个 IPV4 地址。

IPV4 地址有 32 位,一个字节有 8 位,共 4 个字节。

其中127 开头的都属于回环地址,也是 IPV4 的特殊地址,没什么道理,就是人为规定的。

127.0.0.1众多回环地址中的一个。之所以不是 127.0.0.2 ,而是 127.0.0.1,是因为源码里就是这么定义的,也没什么道理。

/* Address to loopback in software to local host.  */
#define    INADDR_LOOPBACK     0x7f000001  /* 127.0.0.1   */

回环地址

IPv4 的地址是 32 位的,2的32次方,大概是40+亿。地球光人口就76亿了,40亿IP这点量,塞牙缝都不够,实际上IP也确实用完了。

所以就有了IPV6IPv6 的地址是 128 位的,大概是2的128次方≈10的38次方。据说地球的沙子数量大概是 10的23次方,所以IPV6的IP可以认为用不完。

IPV4以8位一组,每组之间用 . 号隔开。

IPV6就以16位为一组,每组之间用 : 号隔开。如果全是0,那么可以省略不写。

ipv6回环地址

在IPV4下的回环地址是 127.0.0.1,在IPV6下,表达为 ::1 。中间把连续的0给省略了,之所以不是7个 冒号,而是2个冒号: , 是因为一个 IPV6 地址中只允许出现⼀次两个连续的冒号

多说一句:在IPV4下用的是 ping 127.0.0.1 命令。在IPV6下用的是 ping6  ::1 命令。

什么是 ping

ping 是应用层命令,可以理解为它跟游戏或者聊天软件属于同一层。只不过聊天软件可以收发消息,还能点个赞什么的,有很多复杂的功能。而 ping 作为一个小软件,它的功能比较简单,就是尝试发送一个小小的消息到目标机器上,判断目的机器是否可达,其实也就是判断目标机器网络是否能连通。

ping应用的底层,用的是网络层的ICMP协议

IP和ICMP和Ping所在分层

虽然ICMP协议和IP协议都属于网络层协议,但其实ICMP也是利用了IP协议进行消息的传输

ip和icmp的关系

所以,大家在这里完全可以简单的理解为 ping 某个IP 就是往某个IP地址发个消息。

TCP发数据和ping的区别

一般情况下,我们会使用 TCP 进行网络数据传输,那么我们可以看下它和 ping 的区别。

ping和普通发消息的关系

ping和其他应用层软件都属于应用层

那么我们横向对比一下,比方说聊天软件,如果用的是TCP的方式去发送消息。

为了发送消息,那就得先知道往哪发。linux里万物皆文件,那你要发消息的目的地,也是个文件,这里就引出了socket 的概念。

要使用 socket , 那么首先需要创建它。

在 TCP 传输中创建的方式是  socket(AF_INET, SOCK_STREAM, 0);,其中 AF_INET 表示将使用 IPV4 里 host:port 的方式去解析待会你输入的网络地址。SOCK_STREAM 是指使用面向字节流的 TCP 协议,工作在传输层

创建好了 socket 之后,就可以愉快的把要传输的数据写到这个文件里。调用 socket 的sendto接口的过程中进程会从用户态进入到内核态,最后会调用到 sock_sendmsg 方法。

然后进入传输层,带上TCP头。网络层带上IP头,数据链路层带上 MAC头等一系列操作后。进入网卡的发送队列 ring buffer ,顺着网卡就发出去了。

回到 ping , 整个过程也基本跟 TCP 发数据类似,差异的地方主要在于,创建 socket 的时候用的是  socket(AF_INET,SOCK_RAW,IPPROTO_ICMP)SOCK_RAW 是原始套接字 ,工作在网络层, 所以构建ICMP(网络层协议)的数据,是再合适不过了。ping 在进入内核态后最后也是调用的  sock_sendmsg 方法,进入到网络层后加上ICMP和IP头后,数据链路层加上MAC头,也是顺着网卡发出。因此 本质上ping 跟 普通应用发消息 在程序流程上没太大差别。

这也解释了为什么当你发现怀疑网络有问题的时候,别人第一时间是问你能ping通吗?因为可以简单理解为ping就是自己组了个数据包,让系统按着其他软件发送数据的路径往外发一遍,能通的话说明其他软件发的数据也能通。

为什么断网了还能 ping 通 127.0.0.1

前面提到,有网的情况下,ping 最后是通过网卡将数据发送出去的。

那么断网的情况下,网卡已经不工作了,ping 回环地址却一切正常,我们可以看下这种情况下的工作原理。

ping回环地址

从应用层到传输层再到网络层。这段路径跟ping外网的时候是几乎是一样的。到了网络层,系统会根据目的IP,在路由表中获取对应的路由信息,而这其中就包含选择哪个网卡把消息发出。

当发现目标IP是外网IP时,会从"真网卡"发出。

当发现目标IP是回环地址时,就会选择本地网卡

本地网卡,其实就是个"假网卡",它不像"真网卡"那样有个ring buffer什么的,"假网卡"会把数据推到一个叫 input_pkt_queue链表 中。这个链表,其实是所有网卡共享的,上面挂着发给本机的各种消息。消息被发送到这个链表后,会再触发一个软中断

专门处理软中断的工具人"ksoftirqd" (这是个内核线程),它在收到软中断后就会立马去链表里把消息取出,然后顺着数据链路层、网络层等层层往上传递最后给到应用程序。

工具人ksoftirqd

ping 回环地址和通过TCP等各种协议发送数据到回环地址都是走这条路径。整条路径从发到收,都没有经过"真网卡"。之所以127.0.0.1叫本地回环地址,可以理解为,消息发出到这个地址上的话,就不会出网络,在本机打个转就又回来了。所以断网,依然能 ping127.0.0.1

ping回环地址和ping本机地址有什么区别

我们在mac里执行 ifconfig

$ ifconfig
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
    inet 127.0.0.1 netmask 0xff000000
    ...
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    inet 192.168.31.6 netmask 0xffffff00 broadcast 192.168.31.255
    ...

能看到 lo0,表示本地回环接口,对应的地址,就是我们前面提到的 127.0.0.1 ,也就是回环地址

eth0,表示本机第一块网卡,对应的IP地址是192.168.31.6,管它叫本机IP

之前一直认为ping本机IP的话会通过"真网卡"出去,然后遇到第一个路由器,再发回来到本机。

为了验证这个说法,可以进行抓包,但结果跟上面的说法并不相同。

ping 127.0.0.1

ping 本机地址

可以看到 ping 本机IP 跟 ping 回环地址一样,相关的网络数据,都是走的  lo0,本地回环接口,也就是前面提到的"假网卡"

只要走了本地回环接口,那数据都不会发送到网络中,在本机网络协议栈中兜一圈,就发回来了。因此 ping回环地址和ping本机地址没有区别

127.0.0.1 和 localhost 以及 0.0.0.0 有区别吗

回到文章开头动图里的提问,算是面试八股文里的老常客了。

以前第一次用 nginx 的时候,发现用这几个 IP,都能正常访问到 nginx 的欢迎网页。一度认为这几个 IP 都是一样的。

访问127.0.0.1:80

访问localhost:80

访问0.0.0.0:80

访问本机的IP地址

但本质上还是有些区别的。

首先 localhost 就不叫 IP,它是一个域名,就跟 "baidu.com",是一个形式的东西,只不过默认会把它解析为 127.0.0.1 ,当然这可以在 /etc/hosts 文件下进行修改。

所以默认情况下,使用 localhost  跟使用  127.0.0.1  确实是没区别的。

其次就是 0.0.0.0,执行 ping 0.0.0.0  ,是会失败的,因为它在IPV4中表示的是无效的目标地址

$ ping 0.0.0.0
PING 0.0.0.0 (0.0.0.0): 56 data bytes
ping: sendto: No route to host
ping: sendto: No route to host

但它还是很有用处的,回想下,我们启动服务器的时候,一般会 listen 一个 IP 和端口,等待客户端的连接。

如果此时 listen 的是本机的 0.0.0.0 , 那么它表示本机上的所有IPV4地址

/* Address to accept any incoming messages. */
#define    INADDR_ANY      ((unsigned long int) 0x00000000) /* 0.0.0.0   */

举个例子。刚刚提到的 127.0.0.1192.168.31.6 ,都是本机的IPV4地址,如果监听 0.0.0.0  ,那么用上面两个地址,都能访问到这个服务器。

当然, 客户端 connect 时,不能使用 0.0.0.0 。必须指明要连接哪个服务器IP。

总结

  • 127.0.0.1回环地址localhost域名,但默认等于 127.0.0.1

  • ping 回环地址和 ping 本机地址,是一样的,走的是lo0 "假网卡",都会经过网络层和数据链路层等逻辑,最后在快要出网卡前狠狠拐了个弯, 将数据插入到一个链表后就软中断通知 ksoftirqd 来进行收数据的逻辑,压根就不出网络。所以断网了也能 ping 通回环地址。

  • 如果服务器 listen 的是 0.0.0.0,那么此时用127.0.0.1和本机地址都可以访问到服务。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

面试官:断网了,还能 ping 通 127.0.0.1 吗? 的相关文章

  • Grizzly 和 Servlet 容器上下文

    我试图在我编写的 在 Grizzly 上运行的 Servlet 中获取一些注入的上下文 例如 Session 或 HttpServletRequest 但我所做的似乎都不起作用 整个过程似乎过早地停止了 并出现以下错误 SEVERE Mis
  • 在 Java 中跨平台地播种随机生成器,无需时间

    我几乎同时在两个线程上初始化两个随机数生成器 并且我希望这两个生成器的行为完全不同 我会打电话Random nextInt 7 经常一个接一个地在两台发电机上运行 使用System currentTimeMillis 这不是一个好主意 因为
  • Java 的 System.arraycopy() 对于小数组有效吗?

    是Java的System arraycopy 对于小数组来说是高效的 或者它是本机方法这一事实是否使其可能比简单的循环和函数调用效率低得多 本机方法是否会因跨越某种 Java 系统桥梁而产生额外的性能开销 稍微扩展一下 Sid 所写的内容
  • 无法让远程 EJB 与 Wildfly 上的 EJB 客户端 API 配合使用

    我目前正在努力让远程 EJB 调用在 wildfly 8 x 和 9 x 上工作 详细来说 它是关于使用 EJB 客户端 API 方法从独立客户端应用程序 而不是从另一个应用程序服务器 进行远程调用 远程命名方法适用于我 但不适用于我的场景
  • Spring Rest POST Json RequestBody 不支持内容类型

    当我尝试使用 post 方法发布新对象时 RequestBody 无法识别 contentType Spring 已经配置完毕 POST 可以与其他对象一起使用 但不能与这个特定对象一起使用 org springframework web
  • JPA 为每个项目选择最新实例

    假设我有一个会议实体 每次会议都有一个与会者和一个会议日期 在我的会议表中 我可能为每个与会者举行多个会议 每个会议都有不同的日期 我需要一个 JPA 查询 该查询将为所有与会者仅选择最新的会议 例如 如果我的桌子看起来像这样 Meetin
  • UnsupportedOperationException:特权进程中不允许使用 WebView

    我在用android sharedUserId android uid system 在我的清单中获得一些不可避免的权利 从 HDMI 输入读取安卓盒子 http eweat manufacturer globalsources com s
  • Tomcat JDBC 池中没有足够的空闲连接

    给定以下 Tomcat JDBC 连接设置
  • AIX:IBM Java:java.net.SocketException:连接超时:可能是由于地址无效

    当尝试与我们的服务器建立 SSL 连接时 我们在 IBM AIX 上经常看到以下异常 java net SocketException Socket closed at com sun net ssl internal ssl SSLSoc
  • Java中通过FTP创建文件夹层次结构

    Java 是否有现成的功能可以在远程 FTP 服务器上创建文件夹层次结构 Apache Commons 确实提供了 FTP 客户端 但我找不到创建目录层次结构的方法 它确实允许创建单个目录 makeDirectory 但创建整个路径似乎并不
  • 创建一个 int 类型的随机数组。爪哇

    我需要创建一个随机的 int 数组 并按我自己的类对其进行排序 这是我制作数组的地方 public class MyProgram9 public static void main String args int list new int
  • 在同一台计算机上设置 JBoss 的多个实例

    我在 JBoss 社区中找到了下一页 http www jboss org community wiki ConfigurePorts http www jboss org community wiki ConfigurePorts 有下一
  • Java 8 Stream - 为什么过滤器方法不执行? [复制]

    这个问题在这里已经有答案了 我正在学习使用java流进行过滤 但是过滤后的流没有打印任何内容 我认为过滤器方法没有被执行 我的过滤代码如下 Stream of d2 a2 b1 b3 c filter s gt s startsWith b
  • Jar Manifest 文件的使用混乱

    我正在阅读使用 jar 工具打包 java 应用程序 我注意到 META INF 目录下创建了一个清单文件 对于一个简单的应用程序来说 感觉它没有任何作用 我在 stackoverflow 上搜索以了解 Manifest 文件的用法 我碰到
  • 如何映射 Map

    I tried ManyToMany cascade CascadeType ALL Map
  • Google App Engine数据存储区字符串编码问题

    你好 我正在使用 Google App Engine 进行一个项目 并且需要存储一些字符串 我正在使用 Java 和JDOHelper getPersistenceManagerFactory transactions optional 在
  • JBoss 5 截断 base64 cookie 字符串的尾部 =

    从 JBoss 4 升级到 JBoss 5 后 我注意到最烦人的回归 它截断 base64 cookie 值的尾部等号 我花了很长时间才明白问题不是我的代码而是 JBoss 的 我用 google 搜索了一下 发现这是一个已知的问题issu
  • Admob - 没有广告可显示

    你好 我尝试制作一些在 Android 手机上显示广告的示例程序 并尝试在 v2 2 的模拟器上测试它 代码中的一切似乎都很好 但调试器中的 AdListener 表示 响应消息为零或空 onFailedToReceiveAd 没有广告可显
  • 如何使用 AEM 解析 org.apache.http.ssl?

    最终 我尝试在 Java 代码中使用 AWS S3 库来通过 AEM 启用服务器端 S3 上传 但在安装依赖项和 或由 AEM 识别时遇到了问题 每次我添加新的依赖项时 都会弹出五个问题 在我尝试构建的这个包中 这是我看到的错误 The i
  • Java applet 是否会违反同源策略

    我需要请求一些东西并从其他域获取信息 我知道由于同源政策 javascript 无法做到这一点 我的另一个选择是通过我的服务器发出代理请求 我不希望请求来自我的服务器的 IP 也不想为我的服务器创建额外的负载 并且希望客户端这样做 是否可以

随机推荐

  • C# winfrom设置循环暂停和继续 原文转自:http://blog.csdn.net/qwldcl/article/details/3970784...

    using System using System Collections Generic using System ComponentModel using System Data using System Drawing using S
  • C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例

    C 开发Unity游戏教程循环遍历做出判断及Unity游戏示例 Unity中循环遍历每个数据 并做出判断 很多时候 游戏在玩家做出判断以后 游戏程序会遍历玩家身上大量的所需数据 然后做出判断 即首先判定玩家是否有权限做出这种选择 然后才决定
  • 部署LNMP+zabbix(监控工具)

    目录 一 了解监控工具 1 为什么使用监控工具 2 企业中使用的监控工具 二 部署LNMP zabbix 1 LNMP安装环境 1 安装nginx 2 安装mysql 3 安装php 4 修改配置文件 5 测试 6 数据库授权 2 部署za
  • less切换主题

    less切换主题 核心css变量 less变量 1 定义主题less文件 assets css theme less 默认的主题颜色 primaryColor var primaryColor 000 primaryTextColor va
  • 批处理文件常用命令

    批处理有许多命令 1 Echo 命令 打开回显或关闭请求回显功能 或显示消息 如果没有任何参数 echo 命令将显示当前回显设置 语法 echo on off message Sample echo off echo hello world
  • Cannot create container for service peer1.org2.example.com: Conflict. 解决方案

    I have a docker compose yaml file defining 5 services orderer example com peer0 org1 example com peer1 org1 example com
  • 60-100-020-使用-MySQL 的Show Profile命令

    文章目录 1 概述 2 开启Profile功能 3 常用参数 4 注意点 5 总结 1 概述 前言 Show Profile是mysql提供的可以用来分析当前会话中sql语句执行的资源消耗情况的工具 可用于sql调优的测量 默认情况下处于关
  • Vue3实现九宫格抽奖(思路+完整代码)

    目录 前言 一 实现思路 1 组件结构 2 数据结构 奖品列表 抽奖按钮 v for的抽奖列表 3 组件交互 抽奖顺序 奖品高亮 中奖 二 完整代码 前言 虽然有一些抽奖插件比如lucky canvas来帮助我们快速发开抽奖小活动 但一些高
  • 最全电力电子仿真matlab/simulink仿真 单相全桥/半桥整流仿真 单相半波全波仿真

    最全电力电子仿真matlab simulink仿真 单相全桥 半桥整流仿真 单相半波全波仿真 三相全桥 半桥整流仿真 三相半波全波仿真 三相桥式整流及其有源逆变仿真 单相桥式整流及其无源逆变仿真 升降压斩波电路 boost buck电路仿真
  • 9V电池百科

    通称 层积电池 因其内部构造为6枚微型片状电池堆叠而得名 又名PPP3电池 标称电压9V 实际出厂电压略高 随使用逐渐降低 尺寸规格为宽度26 5mm 厚度17 5mm 高度48 5mm 根据电解物质的不同 种类主要有锂电池 lithium
  • jQuery获取input值的方法

    获取input的checked值是否为true 第一种 if input name item value val attr checked true 判断是否已经打勾 注 name即控件name属性 value即控件value属性 第二种
  • linux文件权限和文件夹权限解读

    基本介绍 使用ll命令可以查看当前文件夹下所有文件的具体信息 输出结果的第一个字段就是描述文件和目录权限的编码 这个字段的第一个字符代表了对象的类型 代表文件 d 代表目录 l 代表链接 c 代表字符型设备 b 代表块设备 n 代表网络设备
  • 机器学习笔记(李宏毅 2021/2022)——第五节:Transformer

    视频 2021 Transformer 上 2021 Transformer 下 self attention变形 一 Transformer应用 Transformer就是一个Sequence to sequence的model 他的缩写
  • 什么是LAMP(LAMP概念详解)

    LAMP是 Linux Apache MySQL PHP Perl Python 的简称 1998年Michael Kunze在电脑杂志C T撰写的文章中首次使用了缩略语LAMP 它所组成的各组件都是开源软件 因此很方便自由的获取 导致这些
  • 百度地图3d效果和卫星图效果

    3D图 3d案例如上图 代码如下
  • LDAP客户端+Samba架设指南

    1 设定使用 LDAP Authenication vi etc ldap conf host 192 168 1 5 base dc ldap dc gmshi dc org URI ldap 192 168 1 5 rootbinddn
  • 106道Java并发和多线程基础面试题大集合(2w字),这波面试稳了~

    前言 Java多线程分类中写了21篇多线程的文章 21篇文章的内容很多 个人认为 学习 内容越多 越杂的知识 越需要进行深刻的总结 这样才能记忆深刻 将知识变成自己的 这篇文章主要是对多线程的问题进行总结的 因此罗列了108个多线程的问题
  • C/C++中递归的定义和调用(如何使用递归)

    目录 递归是什么 递归模板 实例分析 1 阶乘 2 斐波那契数列 3 汉诺塔 递归是什么 先看一下什么叫递归 递归 就是在运行的过程中不断调用自己 直到满足某个条件 构成递归需具备的条件 子问题须与原始问题干同样的事 且更为简洁明了 不能无
  • springboot+vue jwt校验token 单点登录

    SSO Single Sign On 模式 CAS单点登录 OAuth2 分布式 SSO single sign on 模式 单点登录英文全称Single Sign On 简称就是SSO 它的解释是 在多个应用系统中 只需要登录一次 就可以
  • 面试官:断网了,还能 ping 通 127.0.0.1 吗?

    你女神爱不爱你 你问她 她可能不会告诉你 但网通不通 你 ping 一下就知道了 可能看到标题 你就知道答案了 但是你了解背后的原因吗 那如果把 127 0 0 1 换成 0 0 0 0 或 localhost 会怎么样呢 你知道这几个IP