1

making it short:
a server(192.168.0.78) listens on 8013
a client(10.0.2.15) tries to connect the server, getting its local port(eg.54591)

how to make the client close the connection and reuse 54591?
i tried and got:
1. close the connection directly and listen the same port:can not reuse port
2. launch another program(B) to connect server and exit, then tried to listen the port B has used:unknown port

is there a correct way to do this?
code is simple:
client

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

server

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()                                                                                                             
    }                                                                                                                            
}  
user2986683
  • 297
  • 1
  • 4
  • 12

2 Answers2

1

If you want a client to use a specific local port number, you must bind() after you create() but before you connect(). You can specify any local port number (and/or specific interface) with bind.

To reuse a previous port number, you have to make that port number known to the next connection attempt and you must open it with the SO_REUSEADDR "reuse" option each time or the second bind will not be allowed until the first one fully expires (often 2 minutes after it was closed).

Those are C function names. Go will have something similar.

Community
  • 1
  • 1
Brian White
  • 8,332
  • 2
  • 43
  • 67
0

This is a known problem of Go's net package.

There are couple of workarounds, like this package, for instance: https://github.com/jbenet/go-reuseport

Oleksandr Kravchuk
  • 5,963
  • 1
  • 20
  • 31