文章目录
- 前言
- 一、IP地址与MAC地址的作用
- 二、IP基础
- 2.1 基础
- 2.2 IP 地址的分类
- 三、ping的工作原理
- 3.1 ICMP 协议
- 3.2 TCP发数据和ping的区别
- 3.2.1 如果用的是TCP的方式去发送消息
- 3.2.1 如果用的是ping
- 四、断网了,还能 ping 通 127.0.0.1 吗?
- 4.1 什么是127.0.0.1
- 4.2 为什么能ping通
- 4.3 ping回环地址和ping本机地址有什么区别
- 4.4 127.0.0.1 和 localhost 以及 0.0.0.0 有区别吗
前言
TCP/IP 模型主要分为应用层、传输层、网络层、网络接口层
IP 在 TCP/IP 参考模型中处于第三层,也就是网络层。
一、IP地址与MAC地址的作用
IP 的作用是主机之间通信用的,而 MAC 的作用则是实现「直连」的两个设备之间通信,而 IP 则负责在「没有直连」的两个网络之间进行通信传输。
例子:
小林要去一个很远的地方旅行,制定了一个行程表,其间需先后乘坐飞机、地铁、公交车才能抵达目的地,为此小林需要买飞机票,地铁票等。
飞机票和地铁票都是去往特定的地点的,每张票只能够在某一限定区间内移动,此处的「区间内」就如同通信网络中数据链路。
在区间内移动相当于数据链路层,充当区间内两个节点传输的功能,区间内的出发点好比源 MAC 地址,目标地点好比目的 MAC 地址。
整个旅游行程表就相当于网络层,充当远程定位的功能,行程的开始好比源 IP,行程的终点好比目的 IP 地址。
如果小林只有行程表而没有车票,就无法搭乘交通工具到达目的地。相反,如果除了车票而没有行程表,恐怕也很难到达目的地。因为小林不知道该坐什么车,也不知道该在哪里换乘。
因此,只有两者兼备,既有某个区间的车票又有整个旅行的行程表,才能保证到达目的地。与此类似,计算机网络中也需要「数据链路层」和「网络层」这个分层才能实现向最终目标地址的通信。
还有重要一点,旅行途中我们虽然不断变化了交通工具,但是旅行行程的起始地址和目的地址始终都没变。
其实,在网络中数据包传输中也是如此,源IP地址和目标IP地址在传输过程中是不会变化的(前提:没有使用 NAT 网络),只有源 MAC 地址和目标 MAC 一直在变化。
二、IP基础
2.1 基础
一台主机或者网卡可以设置2个以上的IP
2.2 IP 地址的分类
三、ping的工作原理
3.1 ICMP 协议
你女神爱不爱你,你问她,她可能不会告诉你。
但网通不通,你 ping 一下就知道了。
ping 某个IP 就是往某个IP地址发个消息
ping 是基于 ICMP 协议(互联网控制报文协议)工作的
ICMP 主要的功能包括:确认 IP 包是否成功送达目标地址、报告发送过程中 IP 包被废弃的原因和改善网络设置等。
3.2 TCP发数据和ping的区别
ping和其他应用层软件都属于应用层。
3.2.1 如果用的是TCP的方式去发送消息
为了发送消息,那就得先知道往哪发,那你要发消息的目的地,也是个文件,首先创建socket
socket(AF_INET, SOCK_STREAM, 0)
其中 AF_INET
表示将使用 IPV4 里 host:port 的方式去解析待会你输入的网络地址。SOCK_STREAM
是指使用面向字节流的 TCP 协议,工作在传输层。
创建好了 socket 之后,就可以愉快的把要传输的数据写到这个文件里。调用 socket 的 sendto 接口的过程中进程会从用户态进入到内核态,最后会调用到 sock_sendmsg 方法。
然后进入传输层,带上TCP头。网络层带上IP头,数据链路层带上MAC头等一系列操作后。进入网卡的发送队列 ring buffer ,顺着网卡就发出去了。
3.2.1 如果用的是ping
回到 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 吗?
那如果把 127.0.0.1 换成 0.0.0.0 或 localhost 会怎么样呢?你知道这几个IP有什么区别吗?
4.1 什么是127.0.0.1
其中127 开头的都属于回环地址,也是 IPV4 的特殊地址,没什么道理,就是人为规定的。
4.2 为什么能ping通
前面提到,有网的情况下,ping 最后是通过网卡将数据发送出去的。
那么断网的情况下,网卡已经不工作了,ping 回环地址却一切正常,我们可以看下这种情况下的工作原理。
从应用层到传输层再到网络层。这段路径跟ping外网的时候是几乎是一样的。到了网络层,系统会根据目的IP,在路由表中获取对应的路由信息,而这其中就包含选择哪个网卡把消息发出。
当发现目标IP是外网IP时,会从"真网卡"发出。
当发现目标IP是回环地址时,就会选择本地网卡"假网卡"。
本地网卡,其实就是个"假网卡",它不像"真网卡"那样有个ring buffer什么的,"假网卡"会把数据推到一个叫 input_pkt_queue 的 链表 中。这个链表,其实是所有网卡共享的,上面挂着发给本机的各种消息。消息被发送到这个链表后,会再触发一个软中断。
专门处理软中断的工具人"ksoftirqd"(这是个内核线程),它在收到软中断后就会立马去链表里把消息取出,然后顺着数据链路层、网络层等层层往上传递最后给到应用程序。
==ping 回环地址和通过TCP等各种协议发送数据到回环地址都是走的“假网卡”。==整条路径从发到收,都没有经过"真网卡"。之所以127.0.0.1叫本地回环地址,可以理解为,消息发出到这个地址上的话,就不会出网络,在本机打个转就又回来了。所以断网,依然能 ping 通 127.0.0.1。
4.3 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 回环地址一样,相关的网络数据,都是走的 lo0,本地回环接口,也就是前面提到的**“假网卡”**。
只要走了本地回环接口,那数据都不会发送到网络中,在本机网络协议栈中兜一圈,就发回来了。因此 ping回环地址和ping本机地址没有区别。
4.4 127.0.0.1 和 localhost 以及 0.0.0.0 有区别吗
首先 localhost 就不叫 IP,它是一个域名,就跟 “baidu.com”,是一个形式的东西,只不过默认会把它解析为 127.0.0.1 ,当然这可以在 /etc/hosts 文件下进行修改。
127.0.0.1 是回环地址。localhost是域名,但默认等于 127.0.0.1。
其次就是 0.0.0.0,执行 ping 0.0.0.0 ,是会失败的,0.0.0.0在IPV4中表示的是无效的目标地址。
ping 回环地址和 ping 本机地址,是一样的,走的是lo0 “假网卡”,都会经过网络层和数据链路层等逻辑,最后在快要出网卡前狠狠拐了个弯, 将数据插入到一个链表后就软中断通知 ksoftirqd 来进行收数据的逻辑,压根就不出网络。所以断网了也能 ping 通回环地址。
如果服务器 listen 的是 0.0.0.0,那么此时用127.0.0.1和本机地址都可以访问到服务。