如何重用已拨打的tcp端口

时间:2015-11-05 09:03:00

标签: sockets tcp go nat

缩短:
服务器(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()                                                                                                             
    }                                                                                                                            
}  

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

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

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