Go 中的 TCP 连接

TCP Connections in Go

这是我的代码:

package main                                                                       

import (                                                                           
    "fmt"                                                                          
    "net"                                                                          
)                                                                                  

func main() {                                                                      
    addr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:8081")                         
    listener, _ := net.ListenTCP("tcp", addr)                                      
    fmt.Printf("listener addr: %s\n", listener.Addr().String())                    
    for {                                                                          
        conn, err := listener.AcceptTCP()                                          
        if err != nil {                                                            
            // handle error                                                        
            fmt.Println("err")                                                     
            return                                                                 
        }                                                                          
        go handleConnection(conn)                                                  
    }                                                                              
}                                                                                  

func handleConnection(conn *net.TCPConn) {                                         
    fmt.Printf("conn addr: %s\n", conn.LocalAddr().String())                       
    fmt.Printf("conn remote addr: %s\n", conn.RemoteAddr().String())               
}  

输出

listener addr: 127.0.0.1:8081
conn addr: 127.0.0.1:8081
conn remote addr: 127.0.0.1:1234

为什么listenerconn的地址相同?在 TCP 中,我以为为新连接创建了一个新套接字。

不,您的侦听器正在接受端口 8081 中的连接,因此 LocalAddr 将拥有该端口。如果拨出到另一台服务器,通常每次都使用不同的端口,但这也不是必需的。

这让我困惑了一秒钟,但这是正确的。确实创建了一个新套接字(具有唯一的本地+远程地址元组)。 wikipedia 的这句话描述得很好:

A server may create several concurrently established TCP sockets with the same local port number and local IP address, each mapped to its own server-child process, serving its own client process. They are treated as different sockets by the operating system, since the remote socket address (the client IP address and/or port number) are different; i.e. since they have different socket pair tuples.

如果您换个角度思考,即传出连接,看到远程地址在许多套接字上相同(例如 google.com:80),您不会觉得奇怪,因此传入连接也是如此.

可能这样做的一个很好的副作用是像 netstat 这样的工具在检查套接字时会很好地显示源端口,而不是随机对。