Multiaddr是自我描述的网络地址。它很好的改进了目前的网络地址格式,旨在使网络成为未来的证明,可以组合和高效。
目前的寻址方案存在许多问题:
Multiaddr改进了这些问题,它的特性是:
来看一下两者的结构事例:
普通标示:
127.0.0.1:9090 # ip4. is this TCP? or UDP? or something else?
[::1]:3217 # ip6. is this TCP? or UDP? or something else?
http://127.0.0.1/baz.jpg
http://foo.com/bar/baz.jpg
//foo.com:1234
# use DNS, to resolve to either ip4 or ip6, but definitely use
# tcp after. or maybe quic... >.<
# these default to TCP port :80.
而用multiaddr方法标示:
/ip4/127.0.0.1/udp/9090/quic
/ip6/::1/tcp/3217
/ip4/127.0.0.1/tcp/80/http/baz.jpg
/dns4/foo.com/tcp/80/http/bar/baz.jpg
/dns6/foo.com/tcp/443/https
使用multiaddr后,表达的更清晰,而且格式上看着更人性化,可读性高了。
Multiaddr 采用 递归TLV(type+length+value)的格式进行编码,它有两种形式:
人类友好格式定义如下:
(/<addr-protocol-str-code>/<addr-value>)+
机器友好的格式定义如下:
(<addr-protocol-code><addr-value>)+
我们采用 Golang 来使用 multiaddr。
安装 multiaddr
go get github.com/multiformats/go-multiaddr
代码:
package main
import (
"fmt"
ma "github.com/multiformats/go-multiaddr"
)
func main() {
// construct from a string (err signals parse failure)
m1, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234")
if err != nil {
panic(err)
}
// construct from bytes (err signals parse failure)
m2, err := ma.NewMultiaddrBytes(m1.Bytes())
if err != nil {
panic(err)
}
// true
fmt.Println(m2.Equal(m1))
fmt.Println(m1.Protocols())
m3, err := ma.NewMultiaddr("/sctp/5678")
if err != nil {
panic(err)
}
fmt.Println(m1.Encapsulate(m3))
m4, err := ma.NewMultiaddr("/udp/1234")
if err != nil {
panic(err)
}
fmt.Println(m1.Decapsulate(m4))
}
测试:
> go run multiaddr.go
true
[{ip4 4 [4] 32 false {0x4cd930 0x4cdd00 <nil>}} {udp 273 [142 2] 16 false {0x4cdd70 0x4cdf80 <nil>}}]
/ip4/127.0.0.1/udp/1234/sctp/5678
/ip4/127.0.0.1