IPv6仅仅只是“长”吗?IPv6的地址长什么样?平时咱们是怎么使用IPv6的呢?编写网络程序的时候要怎么处理IPv6?且待本篇一一道来。php
全球的IP地址由一个名字叫IANA(Internet Assigned Numbers Authority)的机构管理,在它下面有5个分管机构,名字叫分别叫AFRINIC、APNIC、ARIN、PIPE NCC和LACNIC,他们分别负责全球五个不一样地区的IP地址分配,中国就归APNIC管。html
IANA只负责将IP地址分配给下面的5个分管机构,分管机构再负责将IP地址分配给相关地区的网络运营商或者研究机构等。python
IPv4的长度只有32位,总共约42亿的地址,除去预留的大约6亿地址外,实际在公网中能够被使用的地址大约只有36亿,而据最新统计,世界人口已经超过了70亿,而且截至2016年,人们正在使用的智能手机数量已经超过了20亿。linux
截至2011年01月31日,IANA已经将全部的IP地址分配给了下面的5个分管机构,而到2011年04月15日,APNIC的IP地址已经所有分配完了,就是说,若是咱们的中国电信、移动和联通的IP地址不够用的话,已经没有地方能够申请更多的IP地址了。web
很明显,若是每一个设备都用一个公网IP的话,IPv4早就不够用了,虽然如今用NAT的方式还能坚持一段时间,但终究不是长久之策,咱们须要一个更大的IP地址空间。shell
名字叫IPv6,但它的长度并非64位,而是128位,总的地址空间大约为3.4*10^38,一个亿是10的8次方,那么IPv6就有340万亿亿亿亿个地址(4个亿连一块儿),因此说给地球上的每一粒沙子分配一个IP地址不是在吹牛,是真能够。编程
能够参考这篇文章和这篇文章,里面提到地球上全部沙滩的沙子大约有7.5*10^18粒,这个值跟IPv6的10^38相差了不少个数量级,就算加上沙漠等其它的地方,IPv6的数量也足够覆盖它。ubuntu
IPv6彻底有能力为联网的每一个设备分配一个公网IP,因而咱们能够再也不须要NAT,从而很是方便的实现点到点的直接通讯。浏览器
说好处以前,先了解一下NAT的缺点:安全
使用了NAT以后,每次通讯都要作一次NAT转换,影响性能。
处于两个不一样NAT网络内部的机器不能直接通讯,他们之间的通讯得依赖第三方的服务器,极大的限制了网络的连通性,同时全部的数据都会被第三方所监控。
为了支持NAT,不少网络协议变得很复杂,大大增长了网络的复杂性。
没有了NAT以后,固然上面的这些缺点也就没有了,同时会带来下面这些比较直观的好处:
更方便: 想象一下,每一个电脑都有公网IP,你电脑出了点问题,找我帮忙看一下,只要把你的IP给我,我就能够连上去了,而咱们如今的状况是,两我的都是内网IP,无法直接访问,非得用QQ共享桌面之类的软件。
更安全: 配合点到点的加密,让网络更安全,不给第三方监听的机会; 以网络聊天为例,经过使用点到点的聊天软件,就不用担忧被人监听聊天记录了;同时访问家里的摄像头再也不须要通过第三方服务器,不用担忧给别人看直播了。
IPv6有一个功能叫Stateless Auto Configuration,简单点说,就是能够不借助DHCP服务器实现IP地址的分配,插上网线就能上网。
系统起来后,就会为每一个网卡生成一个Link-Local的IP地址,简单点说就是一个固定的前缀加上mac地址,因为mac地址全球惟一,因此这样构成的IP地址是惟一的,有了这个地址后,就能够局域网进行通讯了,可是这种地址路由器是不会转发的。
若是网络里有路由器; 系统会经过广播的方式问路由器,路由器会返回一个子网前缀,相似于IPv4里面的192.168.0.0/16,系统将子网前缀和mac地址组合起来,构成了一个惟一的IP地址,这个IP地址能够经过路由器路由。
也就是说,就算不作任何配置,系统启动起来后,网卡就必定会有IPv6地址,有了IPv6地址就能够通讯。
固然IP地址也能够由DHCP6服务器来分配,这种方式分配叫作Stateful Auto Configuration。
由Neighbor Discovery代替了IPv4里面的ARP协议,没有ARP后,跟ARP相关的攻击就不存在了
跟IPv4不一样,IPv6包头的字段长度是固定的,没有可选字段,因此路由器不须要检查IP包头是否包含可选字段。
IPv6包头里面没有checksum字段,不须要像IPv4那样每次TTL减1后都须要从新计算包头的checksum。
IPv6不支持在中途被分片和重组,即不能在路由器和防火墙上被分片,从而减轻了路由器的负担。
IPv6包头里面没有checksum,那么会不会不安全呢?若是数据传输的过程当中损坏了怎么办呢?首先,如今的网络都比较好,出现损坏的状况不多;其次,就算损坏了,有两种状况,一种是被路由器丢弃或者发到了错误的主机,这种状况不会形成什么问题,由于IP层原本就不保证可靠的传输,而是由上面的传输层来保证(如TCP),另外一种状况是接受方收到了数据包,但因为数据包受损,内容已经和发送方发出来的不同了,这种状况也是交给上面的传输层协议处理,好比UDP、TCP,它们都有本身的校验码,彻底有能力发现数据损坏的问题。
不容许路由器对IPv6包进行分片,那么怎么保证发送端不会发送太大的数据包呢?首先,IPv6要求入网链路至少能传输1280字节的IP包,若是出现不能传输1280字节IP包这种状况,须要链路层本身处理分片和重组的过程;其次,跟IPv4里面PMTUD(Path MTU Discovery)是可选的不一样,在IPv6里面,PMTUD是一个很是重要且必须的功能;因此通常状况下发送小于等于1280字节的IP包确定能到达目的地,加上如今大部分人都用以太网(MTU为1500,包含以太网的包头),绝大部分状况下一个包过去就能肯定PMTU(Path MTU ),不会影响数据传输性能。
在设计IPv4的时候,根本没有考虑过安全问题。
而在设计IPv6的时候,安全问题做为一个很重要的方面被考虑进来了,尤为是端到端的安全,IPsec正是在这样的背景下被设计出来的,有了IPsec后,在IP层就能实现安全传输。
虽然IPsec也被引入到了IPv4,但因为IPsec连传输层的端口都进行了加密,致使IPsec碰到NAT网络的时候,会形成不少麻烦,虽然如今已经有了解决办法,但IPsec在IPv4网络里面仍是受到诸多限制。
IPv6的包头里面包含了一个叫作Flow Label的字段,专门为QoS服务。
移动网络要求设备能在不一样的网络里面快速的切换,而且现有的通讯不受切换的影响,在IPv6里面,有专门的协议Mobile IPv6 (MIPv6)来处理这个事情。
这里不介绍报文的格式,只介绍IPv6地址的格式。
IPv6地址的128位分红了由冒号分割的8段,每段2个字节16位,这16位由16进制表示,这里是一些例子,左边是完整的格式,右边是缩写格式:
完整的格式 | 缩写格式 |
---|---|
0000:0000:0000:0000:0000:0000:0000:0000 | :: |
0000:0000:0000:0000:0000:0000:0000:0001 | ::1 |
FF02:0000:0000:0000:0000:0000:0000:0001 | FF02::1 |
FC00:0001:A000:0B00:0000:0527:0127:00AB | FC00:1:A000:B00::527:127:AB |
2001:0000:1111:000A:00B0:0000:9000:0200 | 2001:0:1111:A:B0::9000:200 |
2001:0DB8:0000:0000:ABCD:0000:0000:1234 | 2002:DB8::ABCD:0:0:1234 或者 2001:DB8:0:0:ABCD::1234 |
2001:0DB8:AAAA:0001:0000:0000:0000:0100 | 2001:DB8:AAAA:1::100 |
两条缩写规则:
用冒号分割的每段里面的前面的0能够省略掉,如:0001:能够缩写成:1:,:0000:能够缩写成:0:
若是冒号里面的是0的话,能够忽略掉(相邻的多个0能够一块儿忽略掉),直接写成两个冒号,如:0000:0000:能够被缩写成::
注意:若是地址中有多个连续为0的段,只能将其中的一个缩写成::,若是两个都缩写了,就不知道每一个缩写了多少个0,这也是上面的表格中2001:0DB8:0000:0000:ABCD:0000:0000:1234被缩写成2002:DB8::ABCD:0:0:1234或者2001:DB8:0:0:ABCD::1234的缘由,它不能被缩写成2001:DB8::ABCD::1234,通常的作法是哪一种方法省略的0越多就用哪一种。
IPv6和IPv4同样,也有网段和子网的概念,在IPv6里面,表示子网号或者网段的时候,也是相似的方法,如:2001:0:0:CD30::/60,这个时候前面的地址只须要写前60位,后面的全部位都用::来缩写,相似于IPv4里面的192.168.0。0/16,不过要注意的是,这里2001:0:0:CD30::不能把前面的两个0也缩写,由于这样就不是一个合法的IPv6地址了。
IPv6里面有三种地址类型;
Unicast: 单播地址,就是咱们经常使用的地址,惟一标识一个网络接口
Anycast: 任意播(直译有点怪),一类特殊的IP地址,多个网络接口(不一样的设备)都配上相同的地址,往这个地址发送数据的时候,路由器会只发往其中的一个接口,通常发往最近的那一个。(这个好像对实现负载均衡比较有用)
Multicast: 多播地址,表明一类unicast的集合,但往这个地址发送数据的时候,会将数据发给属于这个多播组的每一个unicast地址。
IPv6里面没有相似于IPv4那样单独的广播概念,它的功能被包含在多播里面。
本人对anycast和multicast不是特别了解,因此无法描述的很清楚。
现有的IP地址被分配成以下几大类:
类型 | 前缀 | IPv6表示方法 |
---|---|---|
Unspecified | 00...00 (128位) | ::/128 |
Loopback | 00...01 (128位) | ::1/128 |
Multicast | 11111111 | FF00::/8 |
Link-Local unicast | 1111111010 | FE80::/10 |
Unique local address | 1111110 | FC00::/7 |
Global Unicast | 全部其它 |
全0的地址::/128为未定义地址,你们不要去使用
除了最后一位是1,其它都是0的地址::1/128为本地环回地址,同IPv4里面的127.0.0.1
FF00::/8这个网段的地址都是多播地址
FE80::/10为Link-Local的单播地址,这类地址不能穿过路由器
FC00::/7为本地的单播地址,能够穿过本地的路由器,但不能穿过外网的路由器,即只能够在本地使用,和IPv4里面的192.168.0.0/16类似
全局的单播地址目前只有2000::/3开头的能够被申请使用,其它的都被预留了
这里是两个经常使用的预约义的多播地址:
地址 | 含义 |
---|---|
FF02:0:0:0:0:0:0:1 | 子网内的全部机器 |
FF02:0:0:0:0:0:0:2 | 子网内的全部路由器 |
后面有例子演示如何使用多播
IPv6要求全部的单播(unicast)地址的子网必须是64位的,即下面这种格式:
| 64 bits | 64 bits | +-------------------------+-------------------------+ | subnet ID | interface ID |
若是子网的长度不是64位的话,会致使一些IPv6的功能不可用,详情请参考IPv6 Unicast Address Assignment Considerations。
Interface ID为Modified EUI-64格式,标准里面提供了如何将48位mac地址转换成EUI-64格式的方法。
IPv6标准要求单播地址的子网必须是64位的,主要是为了简化IPv6的管理,同时路由也方便,毕竟如今CPU都是64位的,若是子网号超过64位的话,会给路由形成必定的困难,同时64位的接口ID也比较容易存放一个UUID,好比能够容纳48位的mac地址,为Stateless Auto Configuration的地址分配提供了足够的空间。
64位的子网够用吗?64位的子网已经能够容纳2^64的设备了,至关于40亿个如今的IPv4地址空间的规模,实在是想不出还有哪一种场合须要更大的子网。
64位的子网浪费吗?想一想IPv4时代,几我的或者一群人经过NAT共享1个公网IP,而到了IPv6时代,这些人居然能够拥有2^64个IP地址,想用几个用几个,为几我的分配一个64位的子网是否是有点浪费呢?其实谈不上浪费,IPv6的地址就是有那么多,你们都空着不用也是浪费,按道理64位的IP地址在可预见的未来已经够用了,而之因此采用128位IP加64位子网的方式,是由于能给咱们的管理和使用方面带来不少的方便,如上面提到的便于路由和地址分配等。就算之后IP不够用了,再来放开子网位数的限制应该问题也不大。
想起了一句话: 等我有了钱,要装两条宽带,一条玩游戏,一条聊QQ。
下面的全部例子都在ubuntu-server-x86_64 16.04下执行经过
如今的大部分Linux发行版默认状况下都启用了IPv6,若是没有,请参考发行版相关文档进行配置
#这里有输出,表示IPv6已结启用了 dev@ubuntu:~$ test -f /proc/net/if_inet6 && echo "IPv6 is already enabled" IPv6 is already enabled
IPv6启用后,每一个网卡都会有一个IPv6地址,以下:
dev@ubuntu:~$ ifconfig enp0s3 Link encap:Ethernet HWaddr 08:00:27:03:d0:e7 inet addr:192.168.3.12 Bcast:192.168.3.255 Mask:255.255.255.0 inet6 addr: fe80::a00:27ff:fe03:d0e7/64 Scope:Link ...... lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host ......
这里lo的IPv6地址是环回地址::1,而enp0s3有一个“Scope:Link”的IPv6地址fe80::a00:27ff:fe03:d0e7,这个IP地址即上面说到的Link-local地址,它无法经过路由器,只能在子网内部使用。
因为IPv6对交换机没有要求,因此就算没有支持IPv6的路由器,咱们也能够在本地局域网内试玩一下IPv6
经过ip命令就能够给网卡添加IPv6地址,和一个网卡只能有一个IPv4地址不一样,一个网卡能够配置多个IPv6地址。
#添加一个global的地址 dev@ubuntu:~$ sudo ip -6 addr add 2001::1/64 dev enp0s3 #添加一个Unique local address地址 dev@ubuntu:~$ sudo ip -6 addr add fd00::1/64 dev enp0s3 dev@ubuntu:~$ ifconfig enp0s3 enp0s3 Link encap:Ethernet HWaddr 08:00:27:03:d0:e7 inet addr:192.168.3.12 Bcast:192.168.3.255 Mask:255.255.255.0 inet6 addr: fd00::1/64 Scope:Global inet6 addr: 2001::1/64 Scope:Global inet6 addr: fe80::a00:27ff:fe03:d0e7/64 Scope:Link ......
再来看看系统默认的路由表:
dev@ubuntu:~$ route -A inet6 Kernel IPv6 routing table Destination Next Hop Flag Met Ref Use If 2001::/64 :: U 256 0 0 enp0s3 fd00::/64 :: U 256 0 0 enp0s3 fe80::/64 :: U 256 1 3 enp0s3 ::/0 :: !n -1 1 832 lo ::1/128 :: Un 0 3 36 lo 2001::1/128 :: Un 0 3 9 lo fd00::1/128 :: Un 0 2 5 lo fe80::a00:27ff:fe03:d0e7/128 :: Un 0 3 193 lo ff00::/8 :: U 256 2 84 enp0s3 ::/0 :: !n -1 1 832 lo
从“Next Hop”列能够看出,这里的全部网段都是本地接口能够直接到达的网段,不须要路由器转发。
上节配置好了IPv6以后,咱们这节来看看怎么使用这些地址
这里只用一台机器来演示怎么和本身通讯,你们有条件的话能够试试两台机器之间通讯,效果是同样的。
和IPv4里面的ping相对于的命令是ping6,对于不一样类型的地址,ping的方式不同(为了节省篇幅,示例中省略了ping成功时的输出):
#ping lo的环回地址 dev@ubuntu:~$ ping6 ::1 #ping类型为“Scope:Global”的地址 dev@ubuntu:~$ ping6 fd00::1 dev@ubuntu:~$ ping6 2001::1 #ping类型为“Scope:Link”的地址 dev@ubuntu:~$ ping6 -I enp0s3 fe80::a00:27ff:fe03:d0e7 #ping一个多播(Multicast)地址,ff02::1表明子网中的全部机器 dev@ubuntu:~$ ping6 -I enp0s3 ff02::1 PING ff02::1(ff02::1) from fe80::a00:27ff:fe03:d0e7 enp0s3: 56 data bytes 64 bytes from fe80::a00:27ff:fe03:d0e7: icmp_seq=1 ttl=64 time=0.036 ms 64 bytes from fe80::3aea:a7ff:fe6c:ecff: icmp_seq=1 ttl=64 time=0.744 ms (DUP!) 64 bytes from fe80::188d:cbae:80d5:7a7a: icmp_seq=1 ttl=64 time=0.791 ms (DUP!) ...... #能够看到局域网中的其它机器回复的结果,这些IP都是其它机器的“Scope:Link”地址 #这里(DUP!)是因为ping多播地址时会收到多个回复,致使ping认为有重复的应答,实际上是正常状况 #选择其中的任意一个,单独ping一下试试 dev@ubuntu:~$ ping6 -I enp0s3 fe80::188d:cbae:80d5:7a7a #访问Link-local的地址的时候,除了-I参数外,咱们能够直接这样访问 dev@ubuntu:~$ ping6 fe80::188d:cbae:80d5:7a7a%enp0s3 #或者根据enp0s3的id来访问 #获取enp0s3的id dev@ubuntu:~$ grep enp0s3 /proc/net/if_inet6 | cut -d' ' -f2 | uniq 02 dev@ubuntu:~$ ping6 fe80::188d:cbae:80d5:7a7a%2
从上面能够看出,ping环回地址和global地址时,直接ping就能够了,而ping多播和Link-Local地址时,须要指定从哪一个接口出去,这是由于机器上全部接口的Link-Local地址都属于同一个网段,当有多个接口时,根本没办法自动的判断应该从哪一个接口出去。(不过从上面的路由表里面能够看出,在本地只有一个接口时,已经标识fe80::/64和ff00::/8能够从enp0s3口出去,不肯定为何在这种状况下,应用层的程序还要求指定接口名称,多是为了保持统一吧,无论有几个接口,都同样的用法)。
注意: 若是是访问其它机器的link-local地址,-I参数和百分号的后面必定要指定本机出去的接口名称,而不是目的IP对应的接口名称
DNS里面有一个专门的IPv6类型,叫AAAA,查询的时候指定类型就能够了
#host命令默认状况下只查询A类地址,即IPv4地址 #指定-t AAAA便可查询域名的IPv6地址 #这里的结果显示,baidu.com还不支持IPv6,google.com已经支持了 dev@ubuntu:~$ host -t AAAA baidu.com baidu.com has no AAAA record dev@ubuntu:~$ host -t AAAA google.com google.com has IPv6 address 2607:f8b0:400e:c04::65 #dig命令也是同样的参数 dev@ubuntu:~$ dig -t AAAA google.com #这里省略输出结果,有点长
下面四种方式均可以登录当前机器
dev@ubuntu:~$ ssh ::1 dev@ubuntu:~$ ssh 2001::1 dev@ubuntu:~$ ssh fe80::a00:27ff:fe03:d0e7%enp0s3 dev@ubuntu:~$ ssh fe80::a00:27ff:fe03:d0e7%2
下面以curl来进行演示,若是有图形界面的浏览器的话,能够直接在浏览器里面输入一样的地址
#--------------------------第一个shell窗口---------------------- #准备一个支持IPv6的http服务器 dev@ubuntu:~$ sudo apt-get install php dev@ubuntu:~$ mkdir web dev@ubuntu:~$ echo "hello world!" > web/index.html #启动http服务器,监听全部接口的8080端口 dev@ubuntu:~$ php -S [::]:8080 -t ./web/ PHP 7.0.15-0ubuntu0.16.04.4 Development Server started at Mon Mar 20 23:44:26 2017 Listening on http://[::]:8080 Document root is /home/dev/web Press Ctrl-C to quit. #--------------------------第二个shell窗口---------------------- #确认监听正确,这里:::8080就表示监听了全部IPv6和IPv4接口的8080端口 dev@ubuntu:~$ netstat -anp|grep 8080 tcp6 0 0 :::8080 :::* LISTEN 13716/php #先试试用IPv4的地址连过来,没有问题 dev@ubuntu:~$ curl http://127.0.0.1:8080/ hello world! #IPv6的环回地址 dev@ubuntu:~$ curl http://[::1]:8080/ hello world! #IPv6的global地址 dev@ubuntu:~$ curl http://[2001::1]:8080/ hello world! #link-local地址 dev@ubuntu:~$ curl http://[fe80::a00:27ff:fe03:d0e7%enp0s3]:8080/ hello world! dev@ubuntu:~$ curl http://[fe80::a00:27ff:fe03:d0e7%2]:8080/ hello world!
这里以python代码为示例,写了一个UDP的服务器和客户端,演示如何同时支持IPv4和IPv6。(为了简化起见,代码里面没有作错误处理)
import socket import sys ip,port = sys.argv[1],int(sys.argv[2]) addrinfo = socket.getaddrinfo(ip, port, proto=socket.IPPROTO_UDP)[0] sock = socket.socket(addrinfo[0], socket.SOCK_DGRAM) addr = addrinfo[4] sock.bind(addr) print("Listening on [{}]:{}...".format(addr[0], addr[1])) while True: data, addr = sock.recvfrom(65535) print("Recvfrom [{}]:{}\t{}".format(addr[0], addr[1], data)) sock.sendto(data, addr)
import socket import sys host,port = sys.argv[1],int(sys.argv[2]) addrinfos = socket.getaddrinfo(host, port, proto=socket.IPPROTO_UDP) for addrinfo in addrinfos: sock = socket.socket(addrinfo[0], socket.SOCK_DGRAM) sock.settimeout(2) data = b'hello' addr = addrinfo[4] sock.sendto(data, addr) print("Sendto [{}]:{}\t{}".format(addr[0], addr[1], data)) try: data, addr = sock.recvfrom(65535) print("Recvfrom [{}]:{}\t{}".format(addr[0], addr[1], data)) except socket.timeout: print("timeout")
若是参数传入的是域名或者主机名,getaddrinfo函数可能返回多个IP,这时候客户端须要根据本身的应用特色选择一个或多个进行通讯,在本例中是发送数据包给全部的IP。
getaddrinfo返回的IP列表里面的顺序是有讲究的,若是对这个很在乎的话,请参考rfc6724,默认状况通常是IPv6的地址在前面,在Linux下还能够经过/etc/gai.conf来配置相关的顺序。
dev@ubuntu:~/ipv6$ python3 server.py :: 8000 Listening on [::]:8000... dev@ubuntu:~/ipv6$ python3 server.py 0.0.0.0 8000 Listening on [0.0.0.0]:8000... dev@ubuntu:~/ipv6$ python3 server.py 2001::1 8000 Listening on [2001::1]:8000... dev@ubuntu:~/ipv6$ python3 server.py fe80::a00:27ff:fe03:d0e7%enp0s3 8000 Listening on [fe80::a00:27ff:fe03:d0e7%enp0s3]:8000... dev@ubuntu:~/ipv6$ python3 server.py fe80::a00:27ff:fe03:d0e7%2 8000 Listening on [fe80::a00:27ff:fe03:d0e7%enp0s3]:8000...
dev@ubuntu:~/ipv6$ python3 server.py :: 8000 Listening on [::]:8000... Recvfrom [fe80::a00:27ff:fe03:d0e7%enp0s3]:48033 b'hello' Recvfrom [fe80::a00:27ff:fe03:d0e7%enp0s3]:50298 b'hello' Recvfrom [2001::1]:60882 b'hello' Recvfrom [::1]:44664 b'hello' Recvfrom [::ffff:127.0.0.1]:46676 b'hello' Recvfrom [::1]:55518 b'hello' Recvfrom [::ffff:127.0.0.1]:35961 b'hello' Recvfrom [fe80::a00:27ff:fe03:d0e7%enp0s3]:36281 b'hello'
dev@ubuntu:~/ipv6$ python3 client.py fe80::a00:27ff:fe03:d0e7%enp0s3 8000 Sendto [fe80::a00:27ff:fe03:d0e7%enp0s3]:8000 b'hello' Recvfrom [fe80::a00:27ff:fe03:d0e7%enp0s3]:8000 b'hello' dev@ubuntu:~/ipv6$ python3 client.py fe80::a00:27ff:fe03:d0e7%2 8000 Sendto [fe80::a00:27ff:fe03:d0e7%enp0s3]:8000 b'hello' Recvfrom [fe80::a00:27ff:fe03:d0e7%enp0s3]:8000 b'hello' dev@ubuntu:~/ipv6$ python3 client.py 2001::1 8000 Sendto [2001::1]:8000 b'hello' Recvfrom [2001::1]:8000 b'hello' dev@ubuntu:~/ipv6$ python3 client.py ::1 8000 Sendto [::1]:8000 b'hello' Recvfrom [::1]:8000 b'hello' dev@ubuntu:~/ipv6$ python3 client.py 127.0.0.1 8000 Sendto [127.0.0.1]:8000 b'hello' Recvfrom [127.0.0.1]:8000 b'hello' #因为localhost在/etc/hosts里面配置了两个IP,因此这里发了两个数据包, #而且是先发IPv6的地址 dev@ubuntu:~/ipv6$ python3 client.py localhost 8000 Sendto [::1]:8000 b'hello' Recvfrom [::1]:8000 b'hello' Sendto [127.0.0.1]:8000 b'hello' Recvfrom [127.0.0.1]:8000 b'hello' #经过多播地址发给当前子网中的全部机器 dev@ubuntu:~/ipv6$ python3 client.py FF02:0:0:0:0:0:0:1%enp0s3 8000 Sendto [ff02::1%enp0s3]:8000 b'hello' Recvfrom [fe80::a00:27ff:fe03:d0e7%enp0s3]:8000 b'hello'
Why Allocating a /64 is Not Wasteful and Necessary
Top 10 Features that make IPv6 'greater' than IPv4
IP Version 6 Addressing Architecture