Skip to content

Instantly share code, notes, and snippets.

@joliver
Last active September 27, 2023 22:30
Show Gist options
  • Save joliver/4ccd58605e07e8edf71904b172d95513 to your computer and use it in GitHub Desktop.
Save joliver/4ccd58605e07e8edf71904b172d95513 to your computer and use it in GitHub Desktop.
Go v1.11 net.Listener SO_REUSEPORT or SO_REUSEADDR example
package main
// This is a super-quick example of how to set the socket options to allow port re-use for a single address/port on a host machine.
// This is most commonly used with things like hot reloads of configuration.
import (
"context"
"log"
"net"
"syscall"
)
func main() {
const network = "tcp"
const address = "127.0.0.1:8080"
config := &net.ListenConfig{Control: reusePort}
listener1, _ := config.Listen(context.Background(), network, address) // bind to the address:port
go listen(1, listener1)
// as soon as listener2 is bound below, all traffic will begin to flow it instead of listener1. the only thing left to do
// with listener1 is to shut down any active connections and close the listener.
listener2, _ := config.Listen(context.Background(), network, address) // also bind to the address:port
listen(2, listener2)
}
func listen(id int, listener net.Listener) {
socket, _ := listener.Accept()
log.Println("Accepted socket from listener", id)
socket.Close()
listener.Close()
}
func reusePort(network, address string, conn syscall.RawConn) error {
return conn.Control(func(descriptor uintptr) {
syscall.SetsockoptInt(int(descriptor), syscall.SOL_SOCKET, syscall.SO_REUSEPORT, 1)
})
}
@mholt
Copy link

mholt commented Apr 14, 2022

FYI, I had to find the SO_REUSEPORT identifier in the golang.org/x/sys/unix package (syscall is frozen and my Go distro doesn't have it in there).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment