net
包为网络 I/O 提供了可移植的接口,包括 TCP/IP,UDP,域名解析和 Unix 套接字等.
该软件包提供了对底层网络原语的访问,大多数客户端仅需要 net
包提供的 Dial
和 Listen
函数, Conn
和 Listener
接口相关的的 Accept
方法. crypto/tls
软件包使用相同的接口提供 Dial
和 Listen
函数.
客户端与服务端最简单的通信主要代码示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
ln, err := net.Listen("tcp", "localhost:8080") if err != nil { } for { conn, err := ln.Accept() if err != nil { } go handleConnection(conn) }
conn, err := net.Dial("tcp", "localhost:8080") if err != nil { }
fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")
status, err := bufio.NewReader(conn).ReadString('\n')
|
域名解析
域名解析相关方法因操作系统而异.
Unix 系统上,可以使用纯 Go 解析器将 DNS 请求直接发送到 /etc/resolv.conf
列出的两个 DNS 服务器,也可以使用 cgo 的解析器调用 C 语言库,如 getaddrinfo 和 getnameinfo.
默认情况下使用纯 Go 解释器,可通过如下方式进行修改
1 2
| export GODEBUG=netdns=go export GODEBUG=netdns=cgo
|
Windows 系统上,解析器始终调用 C 语言库函数,如 GetAddrInfo 和 DnsQuery
常用类型定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
type Addr interface { Network() string String() string }
type Conn interface { Read(b []byte) (n int, err error) Write(b []byte) (n int, err error) Close() error LocalAddr() Addr RemoteAddr() Addr SetDeadline(t time.Time) error SetReadDeadline(t time.Time) error SetWriteDeadline(t time.Time) error }
type Listener interface { Accept() (Conn, error) Close() error Addr() Addr }
|
常用函数
net
包函数
1 2 3 4 5 6 7 8 9 10 11
| func Dial(network, address string) (Conn, error) func DialTimeout(network, address string, timeout time.Duration) (Conn, error)
func Listen(network, address string) (Listener, error)
func LookupIP(host string) ([]IP, error)
func ParseIP(s string) IP
|
示例
简单通信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| import ( "fmt" "net" )
func main() { listener, err := net.Listen("tcp", "localhost:9090") if err != nil { fmt.Println(err) return } fmt.Printf("server listen %v\n", listener.Addr()) for { conn, err := listener.Accept() if err != nil { fmt.Println(err) break } go handleConn(conn) } } func handleConn(conn net.Conn) { fmt.Printf("conn established from remote %v\n", conn.RemoteAddr()) buf := make([]byte, 1024) for { rn, err := conn.Read(buf) if err != nil { fmt.Println(err) break } message := string(buf[:rn]) fmt.Printf("client send: %v\n", message) response := "response:" + message conn.Write([]byte(response)) } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import ( "fmt" "net" )
func main() { conn, err := net.Dial("tcp", "localhost:9090") if err != nil { fmt.Println(err) return } fmt.Printf("conn from %v to %v\n", conn.LocalAddr(), conn.RemoteAddr())
conn.Write([]byte("send message")) buf := make([]byte, 1024) n, err := conn.Read(buf) fmt.Printf("recv response: %v", string(buf[:n])) }
|