
在 Go 中通过 net.Conn 接口获取本地地址时,需调用 LocalAddr() 和 RemoteAddr() 方法(而非直接访问字段),否则会因误将方法当作字段而编译失败。
在 go 中通过 `net.conn` 接口获取本地地址时,需调用 `localaddr()` 和 `remoteaddr()` 方法(而非直接访问字段),否则会因误将方法当作字段而编译失败。
Go 的 net.Conn 接口定义中,LocalAddr() 和 RemoteAddr() 均为方法(function),返回 net.Addr 类型值,而非可直接访问的结构体字段。因此,以下写法是错误的:
local := conn.LocalAddr // ❌ 错误:LocalAddr 是方法,不是字段 remote := conn.RemoteAddr // ❌ 同样错误
这会导致编译错误,例如:
local.Network undefined (type func() net.Addr has no field or method Network)
因为 conn.LocalAddr 实际上是函数值(类型为 func() net.Addr),你试图对其调用 .Network 字段,自然失败。
✅ 正确做法是显式调用这两个方法,并对返回的 net.Addr 接口值进行类型断言或直接使用其标准方法(如 .Network() 和 .String()):
func main() {
li, err := net.Listen("tcp", ":8000")
if err != nil {
log.Fatalln("failed to listen:", err)
}
defer li.Close()
fmt.Println("Server listening on :8000...")
for {
conn, err := li.Accept()
if err != nil {
log.Printf("accept error: %v", err)
continue // 避免因单个连接错误终止整个服务
}
// ✅ 正确:调用方法获取地址信息
local := conn.LocalAddr() // 返回 net.Addr 接口
remote := conn.RemoteAddr() // 返回 net.Addr 接口
// 可安全调用 Addr 接口的方法
fmt.Printf("Local: %s (%s)\n", local.String(), local.Network())
fmt.Printf("Remote: %s (%s)\n", remote.String(), remote.Network())
go handleConn(conn)
}
}
func handleConn(conn net.Conn) {
defer conn.Close()
// 处理代理逻辑(如读取请求、转发、写回响应等)
}
⚠️ 注意事项:
-
net.Addr.String()返回地址字符串(如"127.0.0.1:8000"或"[::1]:8000"),适用于日志与调试; -
net.Addr.Network()返回网络类型字符串(如"tcp"、"tcp4"、"tcp6"),对协议适配有参考价值; - 若需解析 IP 和端口,建议使用
net.SplitHostPort(local.String())并做错误处理; - 在高并发代理场景中,应避免在主线程中执行耗时操作(如日志 I/O),必要时可异步记录或批量聚合。
掌握 net.Conn 接口的正确使用方式,是构建健壮 TCP 代理、反向代理或自定义协议服务器的关键基础。











