【问题标题】:how to reuse a dialed tcp port如何重用已拨出的 tcp 端口
【发布时间】:2015-11-05 09:03:00
【问题描述】:

简短地说:
一台服务器(192.168.0.78)监听 8013
客户端(10.0.2.15)尝试连接服务器,获取其本地端口(例如 54591)

如何让客户端关闭连接重用54591?
我试过了:
1.直接关闭连接,监听同一个端口:不能复用端口
2.启动另一个程序(B)连接服务器并退出,然后尝试监听B使用的端口:未知端口

有没有正确的方法来做到这一点?
代码很简单:
客户

func main() {                                                                                                                    
    conn, err := net.Dial("tcp" , "192.168.0.78:8013")                                                                           
    if err != nil {                                                                                                              
        panic(err)                                                                                                               
    }                                                                                                                            
    localAddr := conn.LocalAddr().String()                                                                                       
    conn.Close()                                                                                                                 
    // i got the local port, what to do?                                                                                         
    fmt.Println(localAddr)                                                                                                       
}      

服务器

func main(){                                                                                                                     
    ln, err := net.Listen("tcp", ":8013")                                                                                        
    if err != nil {                                                                                                              
        panic(err)                                                                                                               
    }                                                                                                                            
    for i := 0; i < 5; i++ {                                                                                                     
        conn, err := ln.Accept()                                                                                                 
        if err != nil {                                                                                                          
            panic(err)                                                                                                           
        }                                                                                                                        
        fmt.Println(conn.RemoteAddr().String(), "connected")                                                                     
        conn.Close()                                                                                                             
    }                                                                                                                            
}  

【问题讨论】:

  • 我已经测试了你的代码,但是“直接关闭连接并监听同一个端口”是可以的。没有发生错误。
  • 为什么?你关心客户本地端口是什么?
  • 我得到了这个:恐慌:监听 tcp 10.0.2.15:54613:绑定:地址已经在使用@Ggicci
  • @user2986683 查看github.com/jbenet/go-reuseport

标签: sockets tcp go nat


【解决方案1】:

如果您希望客户端使用特定的本地端口号,您必须在 create() 之后但在 connect() 之前 bind()。您可以使用bind 指定任何本地端口号(和/或特定接口)。

要重用以前的端口号,您必须让下一次连接尝试知道该端口号并且您必须每次都使用SO_REUSEADDR "reuse" option 打开它,否则第二次绑定将直到第一个完全过期(通常在关闭后 2 分钟)才允许。

这些是 C 函数名称。 Go 会有类似的东西。

【讨论】:

  • 我知道,但我只是不知道如何在 go orz 中做同样的事情
【解决方案2】:

这是 Go 的 net 包的一个已知问题。

有几个解决方法,例如这个包,例如:https://github.com/jbenet/go-reuseport

【讨论】:

    猜你喜欢
    • 2011-05-19
    • 1970-01-01
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-25
    相关资源
    最近更新 更多