首页 > 后端开发 > Golang > 在 net/netip 中使用 AddrPort:完整指南

在 net/netip 中使用 AddrPort:完整指南

Patricia Arquette
发布: 2025-01-18 00:14:41
原创
522 人浏览过

Working with AddrPort in net/netip: Complete Guide

继续探索 net/netip 包,我们现在关注 AddrPort,一个优雅地组合 IP 地址和端口号的结构。这种配对是网络编程的基础,对于 Web 服务器、数据库连接和几乎任何网络服务都至关重要。

为什么使用AddrPort?

net/netip 之前,管理 IP:端口组合通常涉及字符串操作,导致解析复杂性和潜在错误。 AddrPort 提供了一种简化的、类型安全的替代方案。

AddrPort 入门

让我们从基础开始:

<code class="language-go">package main

import (
    "fmt"
    "net/netip"
)

func main() {
    // Create from a string
    ap1, err := netip.ParseAddrPort("192.168.1.1:8080")
    if err != nil {
        panic(err)
    }

    // Create from Addr and port
    addr := netip.MustParseAddr("192.168.1.1")
    ap2 := netip.AddrPortFrom(addr, 8080)

    fmt.Printf("From string: %v\nFrom components: %v\n", ap1, ap2)
}</code>
登录后复制

有关端口号的要点:

  • 必须在 0-65535 范围内。
  • 存储为uint16
  • 解析过程中允许使用前导零(“8080”和“08080”是等效的)。

探索 AddrPort 方法

让我们检查一下 AddrPort 可用的方法及其应用程序。

访问地址和端口组件

<code class="language-go">func examineAddrPort(ap netip.AddrPort) {
    // Retrieve the address component
    addr := ap.Addr()
    fmt.Printf("Address: %v\n", addr)

    // Retrieve the port number
    port := ap.Port()
    fmt.Printf("Port: %d\n", port)

    // Obtain the string representation ("<addr>:<port>")
    str := ap.String()
    fmt.Printf("String representation: %s\n", str)
}</code>
登录后复制

处理 IPv4 和 IPv6 地址

AddrPort无缝支持IPv4和IPv6:

<code class="language-go">func handleBothIPVersions() {
    // IPv4 with port
    ap4 := netip.MustParseAddrPort("192.168.1.1:80")

    // IPv6 with port
    ap6 := netip.MustParseAddrPort("[2001:db8::1]:80")

    // Note: Brackets are required for IPv6 addresses.  "2001:db8::1:80" would fail.

    // IPv6 with zone and port
    apZone := netip.MustParseAddrPort("[fe80::1%eth0]:80")

    fmt.Printf("IPv4: %v\n", ap4)
    fmt.Printf("IPv6: %v\n", ap6)
    fmt.Printf("IPv6 with zone: %v\n", apZone)
}</code>
登录后复制

AddrPort 的实际应用

让我们探索 AddrPort 擅长的实际场景。

1. 一个简单的 TCP 服务器

<code class="language-go">func runServer(ap netip.AddrPort) error {
    listener, err := net.Listen("tcp", ap.String())
    if err != nil {
        return fmt.Errorf("failed to start server: %w", err)
    }
    defer listener.Close()

    fmt.Printf("Server listening on %v\n", ap)

    for {
        conn, err := listener.Accept()
        if err != nil {
            return fmt.Errorf("accept failed: %w", err)
        }

        go handleConnection(conn)
    }
}

func handleConnection(conn net.Conn) {
    defer conn.Close()

    // Handle the connection...
}</code>
登录后复制

2. 服务注册中心

此示例演示了管理服务及其端点的服务注册表:

<code class="language-go">// ... (ServiceRegistry struct and methods as in the original example) ...</code>
登录后复制

3.负载均衡器配置

以下是如何在负载均衡器配置中使用 AddrPort

<code class="language-go">// ... (LoadBalancer struct and methods as in the original example) ...</code>
登录后复制

常见模式和最佳实践

  1. 输入验证:始终验证用户提供的输入:
<code class="language-go">func validateEndpoint(input string) error {
    _, err := netip.ParseAddrPort(input)
    if err != nil {
        return fmt.Errorf("invalid endpoint %q: %w", input, err)
    }
    return nil
}</code>
登录后复制
  1. 零值处理: AddrPort 的零值无效:
<code class="language-go">func isValidEndpoint(ap netip.AddrPort) bool {
    return ap.IsValid()
}</code>
登录后复制
  1. 字符串表示形式:AddrPort 存储为字符串时(例如,在配置文件中):
<code class="language-go">func saveConfig(endpoints []netip.AddrPort) map[string]string {
    config := make(map[string]string)
    for i, ep := range endpoints {
        key := fmt.Sprintf("endpoint_%d", i)
        config[key] = ep.String()
    }
    return config
}</code>
登录后复制

与标准库集成

AddrPort 与标准库无缝集成:

<code class="language-go">func dialService(endpoint netip.AddrPort) (net.Conn, error) {
    return net.Dial("tcp", endpoint.String())
}

func listenAndServe(endpoint netip.AddrPort, handler http.Handler) error {
    return http.ListenAndServe(endpoint.String(), handler)
}</code>
登录后复制

性能注意事项

  1. 首选 AddrPortFrom: 当你已经有一个有效的 Addr 时,使用 AddrPortFrom 代替字符串解析以提高效率:
<code class="language-go">addr := netip.MustParseAddr("192.168.1.1")
ap := netip.AddrPortFrom(addr, 8080) // More efficient than parsing "192.168.1.1:8080"</code>
登录后复制
  1. 最小化字符串转换:尽可能保持AddrPort格式的地址,仅在必要时转换为字符串。

下一步是什么?

我们的下一篇文章将介绍Prefix类型,重点关注CIDR表示法和子网操作,完成我们对核心net/netip类型的探索。 在那之前,请在您的网络应用程序中利用 AddrPort 的强大功能和效率!

以上是在 net/netip 中使用 AddrPort:完整指南的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板