Moj*_*ian 16 networking tcp tcpip ip
从理论上讲,IP 地址的每个部分都是 0 到 255 之间的数字(总共 256 个可用插槽)。
但是为什么0
第四部分中没有使用任何IP地址并且它们在IP地址计算中总是从1开始呢?
例如:
127.0.0.1 <=== logically this should start from 0 as the first usable IP address.
192.168.0.1 <=== for example even default router IP address is set to 1 rather than to be 0
10.10.0.1
.
.
Run Code Online (Sandbox Code Playgroud)
为什么0
插槽总是从最后一部分跳过?
use*_*686 34
在 IPv4 中,子网的第一个地址被保留的原因尚不清楚,但很可能是因为很久以前它曾经是“广播”地址。(后来,最后一个地址成为标准广播地址。)
\n因此,现在从技术上讲,可能可以使用第一个地址,但大多数现有网络堆栈仍然将其视为“保留”(有点像整个前“E 类”240.0.0.0/4 空间意外变得不可用)。
\n请注意,它具体是子网的第一个地址,而不总是0
地址。这些仅在 /24 子网的情况下匹配。但例如,/16 子网将.0.0
保留,但不会 .1.0
保留.47.0
\xe2\x80\x93 这些位于 /16 中间的子网,因此它们是完全有效的主机地址。
(另一方面,较小的 /27 子网不仅可以从以下位置开始.0
,还可以从.32
或.192
也将再次保留在 /27 中,即使它们没有保留在 /24 中。)
另请注意,这仅适用于广播子网(例如以太网)。此类地址仍然可以在点对点链接中使用或作为 /32 单独路由。
\n在 IPv4 规范中,任何 IPv4 网络中的最低地址都被保留为网络地址,该地址与广播地址具有不同的用途,而广播地址通常是网络中的最高地址(尽管如果您想找点乐趣,可以进行不同的配置) 。在无类网络和子网掩码出现之前,网络地址的想法更有意义。子网和子网掩码背后的概念是原始规范中不存在的 IPv4 附加概念。
更新:以“.0”结尾的地址没有什么神奇之处,只是它是子网中的最低地址(可能并不总是.0)。
最初,IPv4是有类的,分为5类;A、B、C、D 和 E。A 类网络是最高有效位为 0 的所有 IP,即从 0.0.0.0 到 127.255.255.255 的 IP。高两位为10的IPv4地址为B类地址,对应地址128.0.0.0至191.255.255.255。C 类在其第一个八位字节中以 110xxxxx 开始,或者地址从 192.0.0.0 到 223.255.255.255。D 类的第一个八位字节匹配 1110xxxx,为它们提供 IP 224.0.0.0 到 239.0.0.0。最后,E 类为 1111xxxx 或 IP 240.0.0.0 至 255.255.255.255。E 类地址被视为保留地址,除 255.255.255.255 外,没有明确的用途。D 类是多播地址,用于将数据包一起发送到计算机组。AC 类是普通的单播 IP,其中各个设备在某个网络上获取 IP。
话虽如此,定义每个网络大小的是它的类别。A 类网络被定义为将前 8 位或第一个八位字节作为地址的网络部分,其余 24 位是单个 IPv4 网络上地址的特定于主机的部分。B 类将其分割为 16 位和 16 位或各 2 个八位位组。C类网络使用前24位作为网络部分,最后8位作为主机部分。用现代术语来说,A 类网络具有 /8 子网,B 类网络具有 /16 子网,C 类网络具有 /24 子网。IPv4 地址的网络部分和主机部分之间的分离对于路由数据包非常重要,并且是任何设备决定是否可以将其直接发送到本地网络上的系统还是必须将其发送到路由器以转发到其他地方的方式。在 IPv4 网络堆栈和协议实现子网划分之前,这种区别是从 IP 本身硬编码的。
您可以在 RIPv1 路由协议等协议中看到这一点的残余。它只通告 IP,而不通告子网掩码,因此主机地址和网络地址之间的区别是关键。如果 RIPv1 地址通告的地址为 192.0.0.0,则该地址是 B 类网络中的最低地址,因此它是整个网络的网络地址。它将告诉其他设备从 192.0.0.0 到 192.0.255.255 的所有系统都可以通过该路由使用(因为 B 类使用前两个八位位组作为网络,在本例中为 192.0)。但是,如果它通告 192.0.0.1,则这不是该网络中的最低地址,因此它是主机地址。这意味着 RIPv1 正在为单个特定主机而不是整个网络通告路由。也许它是一个拨号调制解调器,或者有其他原因需要获得唯一的路由,但该广告仅适用于该一台主机。
现在子网很常见,而且 RIPv2 等较新的协议将子网掩码与 IP 一起发送,网络地址的整个概念有点多余,但由于历史原因,我们仍坚持使用它。主机特定路由可以使用子网掩码 255.255.255.255 进行通告,但我们仍然必须保持与假设网络地址存在于网络范围底部的软件的兼容性。
更新:为了进一步澄清,这里有一些例子。如果您要将 10.xxx IP 地址范围分割为 /26 子网,则每个子网总共有 64 个地址(其中 62 个可用于主机),因为 32 位 IP 中仅剩下 6 位可供主机部分使用。前五个子网网络地址为 10.0.0.0、10.0.0.64、10.0.0.128、10.0.0.192 和 10.0.1.0。默认广播地址是子网中的最高地址,分别对应于 10.0.0.63、10.0.0.127、10.0.0.191 和 10.0.1.63。如果改为使用 /23 子网,则每个网络将有 512 个地址(510 个可用)。前五个子网是 10.0.0.0、10.0.2.0、10.0.4.0 和 10.0.6.0。对应的广播地址为10.0.1.255、10.0.3.255、10.5.255和10.7.255。请注意,在后一个示例中,10.0.1.0、10.0.3.0 等不是网络地址。它们完全可以用作主机的常规 IP,因为它们位于子网范围的中间。只有第一个和最后一个地址是特殊的。10.0.0.255 也可以类似地用作常规主机。
但为什么第四部分的IP地址中没有使用0,而IP地址的计算总是从1开始呢?
关于你的问题的标题,至少在Linux下,127.0.0.0
是一个非常有用的地址(就像127.*
映射到环回接口的任何其他地址一样)。
例如,我可以在以下位置启动网络服务器127.0.0.0:8080
:
docker run -d --rm --hostname node1 --name node1 -p 127.0.0.0:8080:8080 alpine \
sh -c "apk add --update darkhttpd; mkdir /srv; hostname > /srv/index.html; darkhttpd /srv --port 8080"
Run Code Online (Sandbox Code Playgroud)
然后启动另一个绑定到127.0.0.1:8080
:
docker run -d --rm --hostname node2 --name node2 -p 127.0.0.1:8080:8080 alpine \
sh -c "apk add --update darkhttpd; mkdir /srv; hostname > /srv/index.html; darkhttpd /srv --port 8080"
Run Code Online (Sandbox Code Playgroud)
现在我可以通过各自的地址访问这些服务器:
$ curl 127.0.0.0:8080
node1
$ curl 127.0.0.1:8080
node2
Run Code Online (Sandbox Code Playgroud)