序:契机
- 因近期产线 opengemini 频繁出问题,为此不得不研究 gemini 的源代码。
: opengemini :
lib/machine/id.go#parseAddr
https://github.com/openGemini/openGemini/blob/main/lib/machine/id.go
# tailf /usr/local/opengemini/gemini-log/logs/ts-sql-8086/sql.log
...
{"level":"warn","time":"2024-12-23T13:36:42.960522422+08:00","msg":"failed to parse address","hostname":"vmw-b.severs.com:8086","error":"invalid address: vmw-b.severs.com:8086","location":"machine/id.go:44","repeated":1}
...
核心API
func SplitHostPort(hostport string) (host, port string, err error)
- 函数功能
将格式为”host:port”、”[host]:port”或”[ipv6-host%zone]:port”的网络地址分割为host或ipv6-host%zone和port两个部分。
- 使用案例: opengemini :
lib/machine/id.go#parseAddr
https://github.com/openGemini/openGemini/blob/main/lib/machine/id.go
func parseAddr(addr string) (net.IP, uint64, error) {
host, port, err := net.SplitHostPort(addr) // 入参 addr := "vmw-b.severs.com:8086" | 出参 host, port, err := vmw-b.severs.com , 8086 , nil <nil>
if err != nil {
return nil, 0, err
}
ip := net.ParseIP(host)//入参 host = "vmw-b.severs.com"
if len(ip) != net.IPv6len {
return nil, 0, errno.NewError(errno.InvalidAddress, addr)
}
ip = ip[net.IPv6len-4:]
if binary.BigEndian.Uint32(ip) == 0 {
return nil, 0, errno.NewError(errno.BadListen, addr)
}
p, _ := strconv.ParseUint(port, 10, 64)
return ip, p, nil
}
等效实验:
package main
import (
"fmt"
"os"
"net"
)
func main() {
addr := "vmw-b.severs.com:8086";
host, port, err := net.SplitHostPort(addr);
fmt.Println("host, port, err:", host, port, err);//host, port, err: vmw-b.severs.com 8086 <nil>
ip := net.ParseIP(host); //入参 host = "vmw-b.severs.com" (错误的入参) | 出参 ip = <nil>
}
func ParseIP(s string) IP
ParseIP parses s as an IP address, returning the result. The string s can be in IPv4 dotted decimal ("192.0.2.1"), IPv6 ("2001:db8::68"), or IPv4-mapped IPv6 ("::ffff:192.0.2.1") form. If s is not a valid textual representation of an IP address, ParseIP returns nil. The returned address is always 16 bytes, IPv4 addresses are returned in IPv4-mapped IPv6 form.
ParseIP将解析为IP地址,并返回结果。字符串s可以是IPv4点分十进制(“192.0.2.1”)、IPv6(“2001:db8::68”)或IPv4映射IPv6(“::ffff:192.0.2.1””)形式。 如果s不是IP地址的有效文本表示,ParseIP将返回
nil`。
返回的地址始终为16个字节,IPv4地址以IPv4映射的IPv6形式返回。
func JoinHostPort(host, port string) string
- 函数功能
将host和port合并为一个网络地址。一般格式为”host:port”;如果host含有冒号或百分号,格式为”[host]:port”。
type HardwareAddr []byte
- HardwareAddr类型代表一个硬件地址(MAC地址)
func ParseMAC(s string) (hw HardwareAddr, err error)
- 函数功能
ParseMAC函数使用如下格式解析一个IEEE 802 MAC-48、EUI-48或EUI-64硬件地址:
01:23:45:67:89:ab
01:23:45:67:89:ab:cd:ef
01-23-45-67-89-ab
01-23-45-67-89-ab-cd-ef
0123.4567.89ab
0123.4567.89ab.cdef
func (a HardwareAddr) String() string
网卡的状态标识
type Flags uint
const (
FlagUp Flags = 1 << iota // 接口在活动状态 1
FlagBroadcast // 接口支持广播 2
FlagLoopback // 接口是环回的 4
FlagPointToPoint // 接口是点对点的 8 可以理解为单播
FlagMulticast // 接口支持组播 16 和多播同义
)
var flagNames = []string{
"up",
"broadcast",
"loopback",
"pointtopoint",
"multicast",
}
func (f Flags) String() string
网卡的相关的方法
type Interface struct {
Index int // 索引,>=1的整数
MTU int // 最大传输单元
Name string // 接口名,例如"en0"、"lo0"、"eth0.100"
HardwareAddr HardwareAddr // 硬件地址,IEEE MAC-48、EUI-48或EUI-64格式
Flags Flags // 接口的属性,例如FlagUp、FlagLoopback、FlagMulticast
}
func Interfaces() ([]Interface, error)
- Interfaces返回该系统的网络接口列表。
例如:(输出结果为了现实方便,使用json输出)
[
{
"Index": 1,
"MTU": 16384,
"Name": "lo0",
"HardwareAddr": null,
"Flags": 21 //相当于 up|loopback|multicast ,网卡使用中,支持环回、组播
},
{
"Index": 9,
"MTU": 1484,
"Name": "awdl0",
"HardwareAddr": "yvQEMXJ1",
"Flags": 18 //相当于broadcast|multicast,网卡未使用,支持广播、组播
},
{
"Index": 5,
"MTU": 1500,
"Name": "en4",
"HardwareAddr": "aFs1niJI",
"Flags": 19 //相当于 up|broadcast|multicast,网卡使用中,支持广播、组播
}
]
func InterfaceByIndex(index int) (*Interface, error)
- InterfaceByIndex返回指定索引的网络接口。
例如
interfaces,_ := net.InterfaceByIndex(5)
json , _ := json.Marshal(interfaces)
输出:
{
"Index": 5,
"MTU": 1500,
"Name": "en4",
"HardwareAddr": "aFs1niJI",
"Flags": 19
}
func InterfaceByName(name string) (*Interface, error)
- InterfaceByName返回指定名字的网络接口
interfaces,_ := net.InterfaceByName("awdl0")
json , _ := json.Marshal(interfaces)
输出:
{
"Index": 9,
"MTU": 1484,
"Name": "awdl0",
"HardwareAddr": "yvQEMXJ1",
"Flags": 18
}
func (ifi *Interface) Addrs() ([]Addr, error)
Addrs方法返回网络接口ifi的一或多个接口地址。
inter,_ := net.InterfaceByIndex(5)
addrs, _ := inter.Addrs()
fmt.Println(addrs)
输出:
[fe80::6a5b:35ff:fe9e:2248/64 10.1.81.38/23]
func (ifi *Interface) MulticastAddrs() ([]Addr, error)
MulticastAddrs返回网络接口ifi加入的多播组地址。
inter,_ := net.InterfaceByIndex(5)
addrs, _ := inter.MulticastAddrs()
json , _ := json.Marshal(addrs)
fmt.Fprintf(c.Writer, string(json))
输出:
[
{
"IP": "224.0.0.251",
"Zone": ""
}, {
"IP": "ff02::fb",
"Zone": ""
},{
"IP": "224.0.0.1",
"Zone": ""
},{
"IP": "ff01::1",
"Zone": ""
}, {
"IP": "ff02::2:ff4d:9ef2",
"Zone": ""
}, {
"IP": "ff02::1",
"Zone": ""
}, {
"IP": "ff02::1:ff9e:2248",
"Zone": ""
}]
网络终端
type Addr interface {
Network() string // 网络名
String() string // 字符串格式的地址
}
X 参考文献
- go
- Go中net包中的方法 - hangdaowangluo.com
- opengemini
https://github.com/openGemini/openGemini/blob/main/app/ts-sql/sql/server.go
[root@vmw-d ~]# tailf /usr/local/opengemini/gemini-log/logs/ts-sql-8086/sql.log
{"level":"error","time":"2024-12-23T10:23:06.166984231+08:00","caller":"transport/node.go:52","msg":"dial failed","hostname":"vmw-d.servers.com:8086","error":"dial tcp [::1]:8092: connect: connection refused"}
{"level":"error","time":"2024-12-23T10:23:08.171332623+08:00","caller":"transport/node.go:52","msg":"dial failed","hostname":"vmw-d.servers.com:8086","error":"dial tcp 192.168.101.103:8092: connect: connection refused"}
{"level":"error","time":"2024-12-23T10:23:09.172203321+08:00","caller":"transport/node.go:52","msg":"dial failed","hostname":"vmw-d.servers.com:8086","error":"dial tcp [::1]:8092: connect: connection refused"}
{"level":"error","time":"2024-12-23T10:23:11.179264372+08:00","caller":"transport/node.go:52","msg":"dial failed","hostname":"vmw-d.servers.com:8086","error":"dial tcp 192.168.101.103:8092: connect: connection refused"}
{"level":"error","time":"2024-12-23T10:23:12.180383605+08:00","caller":"transport/node.go:52","msg":"dial failed","hostname":"vmw-d.servers.com:8086","error":"dial tcp [::1]:8092: connect: connection refused"}
{"level":"info","time":"2024-12-23T10:24:43.435184457+08:00","caller":"syscontrol/syscontrol.go:153","msg":"DisableWrites","switch":false}
{"level":"info","time":"2024-12-23T10:24:43.436841617+08:00","caller":"syscontrol/syscontrol.go:158","msg":"DisableReads","switch":false}
{"level":"info","time":"2024-12-23T10:24:43.442235127+08:00","caller":"app/common.go:287","msg":"TSSQL starting","hostname":"vmw-d.servers.com:8086","version":"v1.2.0","branch":"HEAD","commit":"eb398291ee88b7dde94f431a830e04544bd47e1f","buildTime":"2024-02-29T09:33:29Z"}
{"level":"info","time":"2024-12-23T10:24:43.442277713+08:00","caller":"app/common.go:292","msg":"Go runtime","hostname":"vmw-d.servers.com:8086","version":"go1.21.7","maxprocs":1}
{"level":"warn","time":"2024-12-23T10:24:46.403076232+08:00","msg":"failed to parse address","hostname":"vmw-d.servers.com:8086","error":"invalid address: vmw-d.servers.com:8086","location":"machine/id.go:44","repeated":1}
标签:lang,8086,go,host,error,Go,vmw,net,com
From: https://www.cnblogs.com/johnnyzen/p/18623858