我想知道为什么从客户端也在侦听的地址拨号不起作用(Version A)但侦听客户端拨号到服务器的连接地址实际上有效(Version B)?!谁可以给我解释一下这个。Go对我来说是新的,我仍然在学习很多东西。下面是一个例子:服务器程序:package mainimport . "fmt"import "net"import "os"func main() { Println("server") var listener, listenerError = net.Listen("tcp", "localhost:8080") if listenerError != nil { Println(listenerError) os.Exit(1) } for { con, _ := listener.Accept() // I don't care about the error in this example Printf("LocalAddr: %v\n", con.LocalAddr()) Printf("RemoteAddr: %v\n", con.RemoteAddr()) }}客户端版本 A(不工作):package mainimport "net"import . "fmt"import "os"func main() { var listener, listenerError = net.Listen("tcp", "localhost:0") if listenerError != nil { Println(listenerError) os.Exit(1) } var dialer = new(net.Dialer) dialer.LocalAddr = listener.Addr() con, err := dialer.Dial("tcp", "localhost:8080") if err != nil { // dial tcp 127.0.0.1:60229->127.0.0.1:8080: bind: address already in use Println(err) os.Exit(2) } Printf("LocalAddr: %v\n", con.LocalAddr()) Printf("RemoteAddr: %v\n", con.RemoteAddr())}客户端版本 B(工作):package mainimport "net"import . "fmt"import "os"func main() { Println("client") con, err := net.Dial("tcp", "localhost:8080") if err != nil { Println(err) os.Exit(2) } // magic happens here var listener, listenerError = net.Listen("tcp", con.LocalAddr().String()) if listenerError != nil { Println(listenerError) os.Exit(1) } Println("LISTENING") conn, _ := listener.Accept() // will accept on con.LocalAddr() Printf("LocalAddr: %v\n", conn.LocalAddr()) Printf("RemoteAddr: %v\n", conn.RemoteAddr())}
1 回答
侃侃尔雅
TA贡献1801条经验 获得超15个赞
“版本 B”作为 Go 的 POSIX 默认设置的副作用,即使它被现有连接使用SO_REUSEADDR
,它也允许绑定到一addr:port
对。可以区分这 2 个套接字,因为已建立的连接由 的 4 元组标识(LocalAddr, LocalPort, RemoteAddr, RemotePort)
。
“版本 A”不起作用,因为在设置连接时它需要调用bind
以设置请求的本地地址,并且已经有一个绑定到该端口的侦听套接字。
没有必要尝试利用这个漏洞,您应该为客户端和服务器连接使用 2 个端口。
- 1 回答
- 0 关注
- 181 浏览
添加回答
举报
0/150
提交
取消