什么是Go的net.Listener Addr()用于?

Dav*_*ave 1 go

Go的net.Listener界面如下所示:

type Listener interface {
    // Accept waits for and returns the next connection to the listener.
    Accept() (Conn, error)

    // Close closes the listener.
    // Any blocked Accept operations will be unblocked and return errors.
    Close() error

    // Addr returns the listener's network address.
    Addr() Addr
}
Run Code Online (Sandbox Code Playgroud)

Addr实际使用的是什么?如果我必须实现我自己的监听器,只是返回一个空的,Addr().String()但接受和关闭的连接就好了,会产生什么影响?

Pat*_*ick 8

某些网络协议允许您创建侦听随机地址的侦听器.这是常用的,当你想在同一时间运行服务的多个实例,因此,你不能把它们都监听同一个地址.在这些情况下,内核会找到一个可用的内核,并将您的监听器放在那里.但是一旦你有一个随机地址,你需要知道那个地址是什么,这样你就可以做广告.

例如,使用TCP和UDP,您可以指定0为您的端口号:

package main

import (
    "fmt"
    "net"
)

func main() {
    l, _ := net.Listen("tcp4", ":0")
    fmt.Printf("Addr: %s\n", l.Addr())
}
Run Code Online (Sandbox Code Playgroud)

结果如下:

Addr: 0.0.0.0:37733
Run Code Online (Sandbox Code Playgroud)


Von*_*onC 5

为了增加Patrick的答案,2009年6月在提交5d2ee9d的 Go1.0中添加了这种特殊Addr()的接口类型方法.Listener

当时的原因是:

将Addr()字符串添加到net.Listener接口.

用它来避免在测试中使用固定端口.

这样就net/server_test.go可以监听任何可用的端口,并仍然可以找回确切的地址.

if network == "tcp" {
    listenaddr += ":0"; // any available port
}
go runServe(t, network, listenaddr, listening, done);
addr := <-listening; // wait for server to start
Run Code Online (Sandbox Code Playgroud)

runServe()通过该通道,返回地址使用Addr()方法:

listening <- l.Addr();
Run Code Online (Sandbox Code Playgroud)