11.1.2 网络
网络由一个地址范围定义。通常用一个基本地址和一个掩码表示,掩码指示地址的哪些部分表示网络,哪些部分表示该网络上的地址。可以显式表示掩码,也可以使用一个前缀长度值来表示,如下例所示。
import ipaddress
NETWORKS = [
'10.9.0.0/24',
'fdfd:87b5:b475:5e3e::/64',
]
for n in NETWORKS:
net = ipaddress.ip_network(n)
print('{!r}'.format(net))
print(' is private:',net.is_private)
print(' broadcast:',net.broadcast_address)
print(' compressed:',net.compressed)
print(' with netmask:',net.with_netmask)
print(' with hostmask:',net.with_hostmask)
print(' num addresses:',net.num_addresses)
print()
与地址一样,对于IPv4和IPv6网络分别有两个网络类。每个类都提供了一些属性或方法来访问与网络相关的值,如广播地址和主机可以使用的网络地址。
运行结果:
网络实例是可迭代的,会提供网络上的地址。
import ipaddress
NETWORKS = [
'10.9.0.0/24',
'fdfd:87b5:b475:5e3e::/64',
]
for n in NETWORKS:
net = ipaddress.ip_network(n)
print('{!r}'.format(net))
for i,ip in zip(range(3),net):
print(ip)
print()
这个例子只打印了部分地址,因为IPv6网络可能包含太多的地址,无法在这里全部输出。
运行结果:
迭代处理网络会提供地址,不过并不是所有这些地址都能作为主机的合法地址。例如,网络的基地址和广播地址也包含在内。要查找能够由网络上常规主机使用的地址,可以使用hosts()方法,它会生成一个生成器。
import ipaddress
NETWORKS = [
'10.9.0.0/24',
'fdfd:87b5:b475:5e3e::/64',
]
for n in NETWORKS:
net = ipaddress.ip_network(n)
print('{!r}'.format(net))
for i,ip in zip(range(3),net.hosts()):
print(ip)
print()
将这个例子的输出与前一个例子进行比较,可以看到,主机地址中不包含迭代处理整个网络时生成的前几个值。
运行结果:
除了迭代器协议,网络还支持in操作符,可以用来驱动一个地址是否是一个网络的一部分。
import ipaddress
NETWORKS = [
ipaddress.ip_network('10.9.0.0/24'),
ipaddress.ip_network('fdfd:87b5:b475:5e3e::/64'),
]
ADDRESSES = [
ipaddress.ip_address('10.9.0.6'),
ipaddress.ip_address('10.7.0.31'),
ipaddress.ip_address(
'fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa'
),
ipaddress.ip_address('fe80::3840:c439:b25e:63b0'),
]
for ip in ADDRESSES:
for net in NETWORKS:
if ip in net:
print('{}\nis on {}'.format(ip,net))
break
else:
print('{}\nis not on a know network'.format(ip))
print()
in的实现使用网络掩码来测试地址,所以这比展开网络上的完整地址列表要高效的多。
运行结果: