首页 > 其他分享 >[Go-lang] net包

[Go-lang] net包

时间:2024-12-23 14:21:00浏览次数:8  
标签:lang 8086 go host error Go vmw net com

序:契机

  • 因近期产线 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

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

相关文章

  • cgo 导致 This file is ignored by your gopls build.
    目录1.缺少必要的C开发工具或库2.环境变量设置不正确3.缺少C库或头文件4.gopls设置问题5.构建标签(BuildTags)6.编辑器支持7.测试和验证如果gopls忽略了包含cgo代码的文件,这可能是由于几个原因导致的。cgo允许Go代码调用C代码,但这也引入了一些复杂性,特......
  • 在.NET Core中使用异步多线程高效率的处理大量数据的一种解决方案
    目录一、引言二、假设场景三、解决方案四、示例代码一、引言处理大量数据是一个常见的需求,传统的同步处理方式往往效率低下,尤其是在数据量非常大的情况下。本篇将介绍一种高效的多线程异步处理大数据量的方法,通过边处理边消费的方式,极大地提高了处理效率,并且减少了内存开销。这......
  • Golang 接入 NSQ 实现消费者和生产者
            在现代分布式系统中,消息队列是不可或缺的组件,它允许系统之间异步传递消息,从而实现解耦和高效的处理。NSQ是一个高性能、分布式的消息队列,它适合于处理高吞吐量的消息传递。接下来,我将将介绍如何在Golang中接入NSQ实现生产者和消费者。什么是NSQ?NSQ是......
  • .net framework 4.7.2 框架winform项目升级到.net 8.0项目 log4net不起作用的解决办法
    问题描述:在.netframework4.7.2框架中的winform项目,引入log4net作为日志组件使用,一切正常,可以正常输出日志。但项目框架升级到.net8.0后,log4net的使用就报错,虽然网上有很多关于.net8.0配置并使用log4net的方法,但有些我尝试没有用,有些代码所在位置看不懂在哪用。最后,我想到了......
  • Linux golang安装
    目录方法一:使用包管理器安装(推荐对于大多数用户)对于基于Debian/Ubuntu的系统:对于基于RedHat/CentOS的系统:方法二:从官方网站下载并手动安装(推荐对于需要特定版本的用户)在Linux上安装Go(Golang)可以通过以下几种方式进行。以下是两种最常用的方法:通过包管理器安装和从官方......
  • Kubernetes Gateway API
    KubernetesGatewayAPIGatewayAPI是Kubernetes1.19版本引入的一种新的API规范,会成为Ingress的下一代替代方案。主要原因是Ingress资源对象不能很好的满足网络需求,很多场景下Ingress控制器都需要通过定义annotations或者crd来进行功能扩展,这对于使用标准和支持......
  • .net framework 4.7.2 winform框架项目升级到.net 8.0项目 界面比列失调问题解决
    一、问题发生前:在.netframework4.7.2winform框架开发的项目之前在.netframework4.7.2开发的winform项目,在visualstudio一打开的时候,虽然界面内有些控件也会失调,但是他会提示“使用100%缩放比例重新启动VisualStudio”点击“使用100%缩放比例重新启动VisualStudio”......
  • 防止Django信号互相干扰的方式
    如果书写了多个信号,可能会出现互相干扰的情况。为了防止这种情况的发生,我们可以手动控制信号的断开与连接。#导入依赖fromdjango.db.models.signalsimportpost_savefromdjango.dispatchimportreceiverdefdisconnect_signals():post_save.disconnect(信号1,se......
  • 我的世界服务器搭建教程 兼容Paper核心 兼容Spigot核心
    注意:该服务器是基于Paper1.20.1核心进行初始化,默认兼容spigot插件。一、配置JDK环境二、服务器核心配置三、服务器启动四、加入游戏现在搭建出来的是原版生存服务器,接下来需要进行安装各种插件,包含登录认证;经济;商店;圈地;传送;多地图等可玩性插件。具体内容请看下一章。......
  • Java与容器化:如何使用Docker和Kubernetes优化Java应用的部署
    在现代软件开发中,容器化技术已成为提升应用部署和管理效率的关键工具。Java应用由于其庞大的依赖性和较大的体积,常常在传统环境下部署存在挑战。幸运的是,Docker和Kubernetes的出现为Java应用的开发、部署和管理带来了极大的便利。本文将介绍如何通过Docker和Kubernetes优化Java......