GO语言中的net库简介

Go 的 net 库是一个非常重要的标准库,它提供了对网络协议的支持,尤其是在进行网络编程、构建网络服务和通信时,极大简化了开发工作。net 包提供了多种功能,包括 TCP、UDP、Unix 套接字、DNS 查询等。

以下是 net 包的一些核心功能和常见用法的详细介绍。详情见: https://studygolang.com/pkgdoc

1. net 包的基本功能

1.1 网络连接

net 包允许你创建、接受、关闭网络连接,支持不同的协议(如 TCP、UDP、Unix 套接字等)。

常用的网络连接类型包括:

  • TCP连接(面向连接的协议)
  • UDP连接(无连接的协议)
  • Unix 套接字(本地进程间通信)

2. 基本示例

2.1 TCP 客户端和服务器

创建一个 TCP 服务器
package main

import (
    "fmt"
    "log"
    "net"
    "os"
)

func main() {
    // 监听端口
    listener, err := net.Listen("tcp", ":8080")
    if err != nil {
        log.Fatal(err)
    }
    defer listener.Close()

    fmt.Println("Listening on port 8080...")

    for {
        // 接受客户端连接
        conn, err := listener.Accept()
        if err != nil {
            log.Fatal(err)
        }
        // 处理连接
        go handleConnection(conn)
    }
}

func handleConnection(conn net.Conn) {
    fmt.Println("New connection established:", conn.RemoteAddr())
    defer conn.Close()

    // 向客户端发送消息
    conn.Write([]byte("Hello from server!\n"))
}
创建一个 TCP 客户端
package main

import (
    "fmt"
    "log"
    "net"
)

func main() {
    // 连接到服务器
    conn, err := net.Dial("tcp", "localhost:8080")
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    // 接收服务器的消息
    buffer := make([]byte, 1024)
    n, err := conn.Read(buffer)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("Received:", string(buffer[:n]))
}

在这个例子中,TCP 服务器监听端口 8080,客户端通过 net.Dial 连接到该服务器并读取响应。

2.2 UDP 客户端和服务器

创建一个 UDP 服务器
package main

import (
    "fmt"
    "log"
    "net"
)

func main() {
    // 监听端口
    addr := "localhost:8080"
    pc, err := net.ListenPacket("udp", addr)
    if err != nil {
        log.Fatal(err)
    }
    defer pc.Close()

    fmt.Println("Listening on", addr)

    buffer := make([]byte, 1024)
    for {
        // 接收客户端消息
        n, addr, err := pc.ReadFrom(buffer)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("Received message: %s from %s\n", string(buffer[:n]), addr)
    }
}
创建一个 UDP 客户端
package main

import (
    "fmt"
    "log"
    "net"
)

func main() {
    addr := "localhost:8080"
    // 连接到服务器
    conn, err := net.Dial("udp", addr)
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    // 发送消息
    message := []byte("Hello, UDP server!")
    _, err = conn.Write(message)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("Message sent to UDP server:", string(message))
}

UDP 是无连接的,因此不需要建立连接,只需使用 net.Dial 发送数据并直接读取。

3. 网络地址解析

net 包提供了用于解析主机地址和服务信息的函数。比如,我们可以解析 IP 地址、主机名、端口等。

3.1 获取本机 IP 地址

package main

import (
    "fmt"
    "log"
    "net"
)

func main() {
    // 获取本机所有网络接口的地址
    addrs, err := net.InterfaceAddrs()
    if err != nil {
        log.Fatal(err)
    }

    for _, addr := range addrs {
        fmt.Println("Interface address:", addr)
    }
}

3.2 IP 和主机名解析

package main

import (
    "fmt"
    "log"
    "net"
)

func main() {
    // 解析主机名
    ip, err := net.LookupIP("www.google.com")
    if err != nil {
        log.Fatal(err)
    }

    for _, addr := range ip {
        fmt.Println("IP Address:", addr)
    }

    // 解析 IP 地址
    names, err := net.LookupAddr("8.8.8.8")
    if err != nil {
        log.Fatal(err)
    }

    for _, name := range names {
        fmt.Println("Host name:", name)
    }
}

4. 网络连接的关闭和超时

在 Go 中,net.Conn 接口表示一个网络连接,包含了 Close() 方法,用于关闭连接。此外,DialListen 方法支持设置超时,防止连接一直阻塞。

4.1 设置连接超时

package main

import (
    "fmt"
    "log"
    "net"
    "time"
)

func main() {
    // 设置连接超时
    conn, err := net.DialTimeout("tcp", "localhost:8080", 5*time.Second)
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    fmt.Println("Connected to server:", conn.RemoteAddr())
}

4.2 设置监听超时

package main

import (
    "fmt"
    "log"
    "net"
    "time"
)

func main() {
    listener, err := net.Listen("tcp", ":8080")
    if err != nil {
        log.Fatal(err)
    }
    defer listener.Close()

    // 设置监听超时
    listener.SetDeadline(time.Now().Add(10 * time.Second))

    fmt.Println("Listening on port 8080...")
    conn, err := listener.Accept()
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    fmt.Println("Accepted connection:", conn.RemoteAddr())
}

5. Unix 套接字

net 包还支持 Unix 域套接字(Unix socket),这对于本地进程间的通信非常有用。

5.1 Unix 套接字客户端和服务器

Unix 套接字服务器
package main

import (
    "fmt"
    "log"
    "net"
)

func main() {
    // 创建 Unix 套接字监听器
    listener, err := net.Listen("unix", "/tmp/unixsocket")
    if err != nil {
        log.Fatal(err)
    }
    defer listener.Close()

    fmt.Println("Unix socket server listening on /tmp/unixsocket")

    for {
        conn, err := listener.Accept()
        if err != nil {
            log.Fatal(err)
        }
        go handleConnection(conn)
    }
}

func handleConnection(conn net.Conn) {
    fmt.Println("New connection:", conn.RemoteAddr())
    defer conn.Close()

    // 向客户端发送响应
    conn.Write([]byte("Hello from Unix socket server!\n"))
}
Unix 套接字客户端
package main

import (
    "fmt"
    "log"
    "net"
)

func main() {
    // 连接到 Unix 套接字服务器
    conn, err := net.Dial("unix", "/tmp/unixsocket")
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    // 读取服务器响应
    buffer := make([]byte, 1024)
    n, err := conn.Read(buffer)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("Received:", string(buffer[:n]))
}

6. 总结

net 包是 Go 语言中用于网络编程的核心库之一,提供了丰富的功能,包括:

  • 支持多种协议:TCP、UDP、Unix 套接字等。
  • 提供连接管理(创建、关闭、超时设置等)。
  • 地址解析功能(主机名、IP、DNS 查询等)。
  • 提供了简洁的接口和高效的并发处理机制。

通过 net 包,你可以很方便地构建高效、灵活的网络应用。如果你对某一方面有更多问题,或者需要更深入的实例和技术细节,随时可以继续提问!


文章标签:

评论(0)