0

0

如何在 Go 中正确获取 TCP 连接中客户端的 IP 和端口号

心靈之曲

心靈之曲

发布时间:2026-01-09 16:32:03

|

782人浏览过

|

来源于php中文网

原创

如何在 Go 中正确获取 TCP 连接中客户端的 IP 和端口号

go 的 tcp 服务端程序中,调用 `conn.remoteaddr()` 即可准确获取客户端的 ip 地址和源端口号,该方法返回的地址与操作系统底层网络状态(如 `netstat`)完全一致,无需额外解析或调试。

在基于 Go 编写的 TCP 服务器中,当通过 listener.Accept() 接收一个新连接后,得到的 net.Conn 接口提供了两个关键地址方法:LocalAddr() 和 RemoteAddr()。其中:

  • conn.LocalAddr() 返回的是服务端监听套接字的本地地址(例如 127.0.0.1:8080),即服务器自身绑定的 IP 和端口;
  • conn.RemoteAddr() 返回的是客户端发起连接时使用的实际 IP 和源端口(例如 127.0.0.1:63418),这才是你需要的“客户端 IP:Port”。

⚠️ 注意:部分开发者误以为 RemoteAddr() 返回的端口不正确,通常是由于混淆了「客户端绑定端口」与「客户端连接时由内核分配的临时源端口」。TCP 客户端在调用 net.Dial() 时若未显式 Bind(),系统会自动分配一个可用的 ephemeral port(通常在 32768–65535 范围),而 conn.RemoteAddr() 正是返回这个真实通信源端口——它与 netstat -an 或 lsof -i 输出完全一致,绝对可靠

以下是一个最小可验证示例:

package main

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

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

    fmt.Println("Server listening on :8080...")
    for {
        conn, err := ln.Accept()
        if err != nil {
            fmt.Printf("Accept error: %v\n", err)
            continue
        }

        // ✅ 正确获取客户端地址:IP + 实际源端口
        clientAddr := conn.RemoteAddr()
        fmt.Printf("New connection from: %s\n", clientAddr)

        // 可选:提取 IP 和端口进行进一步处理
        if addr, ok := clientAddr.(*net.TCPAddr); ok {
            fmt.Printf("Client IP: %s, Port: %d\n", addr.IP, addr.Port)
        }

        // 简单响应后关闭(仅用于演示)
        conn.Write([]byte("Hello from server!\n"))
        time.Sleep(100 * time.Millisecond)
        conn.Close()
    }
}

运行此服务端后,使用任意客户端(如 nc 127.0.0.1 8080 或自定义 Go 客户端)连接,控制台将输出类似:

Content at Scale
Content at Scale

SEO长内容自动化创作平台

下载
New connection from: 127.0.0.1:54321
Client IP: 127.0.0.1, Port: 54321

同时在终端执行 netstat -an | grep :8080,你将看到匹配的 ESTABLISHED 行:

tcp4  0  0  127.0.0.1.8080   127.0.0.1.54321   ESTABLISHED

✅ 总结:

  • 始终使用 conn.RemoteAddr() 获取客户端地址;
  • 其返回值类型为 net.Addr,可断言为 *net.TCPAddr 以安全访问 .IP 和 .Port 字段;
  • 无需手动解析、无需依赖 conn.LocalAddr()、更不必绕道系统调用或日志分析;
  • 在同一主机上的进程间通信(localhost)、跨网络通信、IPv4/IPv6 场景下均表现一致。

这是 Go 标准库对 TCP 协议的规范封装,简洁、高效且跨平台可靠。

相关专题

更多
硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1009

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

57

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

353

2025.12.29

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

382

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

567

2023.08.10

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

3

2026.01.09

c++框架学习教程汇总
c++框架学习教程汇总

本专题整合了c++框架学习教程汇总,阅读专题下面的文章了解更多详细内容。

7

2026.01.09

学python好用的网站推荐
学python好用的网站推荐

本专题整合了python学习教程汇总,阅读专题下面的文章了解更多详细内容。

10

2026.01.09

学python网站汇总
学python网站汇总

本专题整合了学python网站汇总,阅读专题下面的文章了解更多详细内容。

1

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 3.5万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号