在Go语言中的TCP连接

huangapple go评论65阅读模式
英文:

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 {
			// 处理错误
			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中,我以为每个新连接都会创建一个新的套接字。

英文:

Here is my code:

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())               
}  

Output

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

Why do listener and conn have the same address? In TCP, I thought a new socket was created for new connections.

答案1

得分: 0

不,您的监听器正在端口8081上接受连接,因此LocalAddr将具有该端口。如果您向另一个服务器拨号,通常每次都会使用不同的端口,尽管这并非必需。

英文:

No, your Listener is accepting connections in port 8081, so the LocalAddr is going to have that port. If you dial out to another server, you usually use a different port each time, though that's not required either.

答案2

得分: 0

这让我困惑了一会儿,但是这是正确的。确实创建了一个新的套接字(具有唯一的本地+远程地址元组)。维基百科上的这段引用描述得很好:

> 服务器可以使用相同的本地端口号和本地IP地址创建多个并发建立的TCP套接字,每个套接字映射到自己的服务器子进程,为自己的客户端进程提供服务。它们在操作系统中被视为不同的套接字,因为远程套接字地址(客户端IP地址和/或端口号)是不同的;也就是说,它们具有不同的套接字对元组。

如果你从另一个角度考虑,即出站连接,你会发现在许多套接字上看到相同的远程地址(例如google.com:80)并不奇怪,所以对于入站连接也是一样的。

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

英文:

It got me puzzled for a second, but this is correct. A new socket is indeed created (with a unique local+remote address tuple). This quote from wikipedia describes it pretty well:

> 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.

If you think about it other way around, i.e. outgoing connection, you don't find it strange seeing remote address being the same across many sockets (e.g. google.com:80), so the same holds for incoming connections.

Probably a nice side effect of this is that tools like netstat, when inspecting sockets, are nicely showing the source port, instead of random pairs.

huangapple
  • 本文由 发表于 2015年3月2日 04:55:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/28798964.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定