golang net 包的功能概述
Go语言中的 net 包提供了一个可移植的网络输入输出接口,涵盖了 TCP/IP、UDP、域名解析以及 Unix 域套接字等功能。
该包提供了访问底层网络原语的能力,但大多数客户端仅需使用基本接口,这包括 Dial、Listen 和 Accept 函数以及相关的 Conn 和 Listener 接口。
crypto/tls 包也利用了相同的接口,并提供了类似的连接和监听函数。
Dial 函数用于连接服务器,例如通过指定网络类型(如 "tcp")和地址(如 "golang.org:80")建立连接。
Listen 函数用于创建服务器,同样需要指定网络类型和监听地址(如 ":8080")。
之后服务器通过 Accept 函数接受传入的连接。
// The Dial function connects to a server: conn, err := net.Dial("tcp", "golang.org:80") if err != nil { // handle error } fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n") status, err := bufio.NewReader(conn).ReadString('\n') // ... // The Listen function creates servers: ln, err := net.Listen("tcp", ":8080") if err != nil { // handle error } for { conn, err := ln.Accept() if err != nil { // handle error } go handleConnection(conn) }
在域名解析方面,无论是间接通过 Dial 等函数还是直接通过 LookupHost、LookupAddr 等函数,其解析方式依据操作系统而异。
在类Unix系统中,解析器有两种解析域名的选项:
一是使用纯 Go 解析器,直接向 /etc/resolv.conf 文件中列出的DNS服务器发送请求;
二是使用基于 cgo 的解析器,调用C库例程如 getaddrinfo 和 getnameinfo。默认情况下,Go倾向于使用纯Go解析器以减少系统线程的消耗,但在特定条件下会自动切换到 cgo 解析器。
用户可以通过设置环境变量 GODEBUG 或编译标签来强制使用某一种解析器,并可以开启调试信息输出以了解解析器的决策过程。
在 macOS 上,当Go代码以 -buildmode=c-archive 模式构建并链接到C程序时,需要在链接C代码时添加 -lresolv 选项。
而在 Plan 9 系统上,解析器始终访问 /net/cs 和 /net/dns。
对于Windows系统,在 Go 1.18 及更早版本中,解析器始终使用C库函数如 GetAddrInfo 和 DnsQuery 来进行域名解析。