81 lines
1.7 KiB
Go
81 lines
1.7 KiB
Go
package network
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"time"
|
|
)
|
|
|
|
func IsPortAvailable(port int) bool {
|
|
return IsTCPPortAvailable(port) && IsUDPPortAvailable(port)
|
|
}
|
|
|
|
func IsTCPPortAvailable(port int) bool {
|
|
addr := fmt.Sprintf(":%d", port)
|
|
listener, err := net.Listen("tcp", addr)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
listener.Close()
|
|
return true
|
|
}
|
|
|
|
func IsUDPPortAvailable(port int) bool {
|
|
conn, err := net.ListenUDP("udp", &net.UDPAddr{Port: port})
|
|
if err != nil {
|
|
return false
|
|
}
|
|
conn.Close()
|
|
return true
|
|
}
|
|
|
|
func FindAvailablePort(startPort int) (int, error) {
|
|
maxPort := 65535
|
|
for port := startPort; port <= maxPort; port++ {
|
|
if IsPortAvailable(port) {
|
|
return port, nil
|
|
}
|
|
}
|
|
return 0, fmt.Errorf("no available ports found between %d and %d", startPort, maxPort)
|
|
}
|
|
|
|
func FindAvailablePortRange(startPort, count int) ([]int, error) {
|
|
maxPort := 65535
|
|
ports := make([]int, 0, count)
|
|
currentPort := startPort
|
|
|
|
for len(ports) < count && currentPort <= maxPort {
|
|
available := true
|
|
for i := 0; i < count-len(ports); i++ {
|
|
if !IsPortAvailable(currentPort + i) {
|
|
available = false
|
|
currentPort += i + 1
|
|
break
|
|
}
|
|
}
|
|
|
|
if available {
|
|
for i := 0; i < count-len(ports); i++ {
|
|
ports = append(ports, currentPort+i)
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(ports) < count {
|
|
return nil, fmt.Errorf("could not find %d consecutive available ports starting from %d", count, startPort)
|
|
}
|
|
|
|
return ports, nil
|
|
}
|
|
|
|
func WaitForPortAvailable(port int, timeout time.Duration) error {
|
|
deadline := time.Now().Add(timeout)
|
|
for time.Now().Before(deadline) {
|
|
if IsPortAvailable(port) {
|
|
return nil
|
|
}
|
|
time.Sleep(100 * time.Millisecond)
|
|
}
|
|
return fmt.Errorf("timeout waiting for port %d to become available", port)
|
|
}
|