first commit
Some checks failed
Build Multi-Platform Binaries / build (amd64, darwin) (push) Failing after 5m51s
Build Multi-Platform Binaries / build (amd64, windows) (push) Has been cancelled
Build Multi-Platform Binaries / build (arm64, darwin) (push) Has been cancelled
Build Multi-Platform Binaries / build (arm64, linux) (push) Has been cancelled
Build Multi-Platform Binaries / build (amd64, linux) (push) Has been cancelled

This commit is contained in:
Flik
2025-12-25 16:19:53 +08:00
commit 0738aa5d93
13 changed files with 884 additions and 0 deletions

78
pkg/utils/port.go Normal file
View File

@@ -0,0 +1,78 @@
package utils
import (
"fmt"
"net"
"sync"
"time"
)
// PortManager 端口管理器
type PortManager struct {
mu sync.RWMutex
occupied map[int]string // port -> clientID
}
// NewPortManager 创建端口管理器
func NewPortManager() *PortManager {
return &PortManager{
occupied: make(map[int]string),
}
}
// IsPortAvailable 检测端口是否可用(系统级)
func IsPortAvailable(port int) bool {
addr := fmt.Sprintf(":%d", port)
ln, err := net.Listen("tcp", addr)
if err != nil {
return false
}
ln.Close()
return true
}
// Reserve 预留端口给指定客户端
func (pm *PortManager) Reserve(port int, clientID string) error {
pm.mu.Lock()
defer pm.mu.Unlock()
if owner, exists := pm.occupied[port]; exists {
return fmt.Errorf("port %d already occupied by client %s", port, owner)
}
if !IsPortAvailable(port) {
return fmt.Errorf("port %d is occupied by system", port)
}
pm.occupied[port] = clientID
return nil
}
// Release 释放端口
func (pm *PortManager) Release(port int) {
pm.mu.Lock()
defer pm.mu.Unlock()
delete(pm.occupied, port)
}
// ReleaseByClient 释放指定客户端的所有端口
func (pm *PortManager) ReleaseByClient(clientID string) {
pm.mu.Lock()
defer pm.mu.Unlock()
for port, owner := range pm.occupied {
if owner == clientID {
delete(pm.occupied, port)
}
}
}
// CheckLocalService 检测本地服务是否可连接
func CheckLocalService(ip string, port int, timeout time.Duration) error {
addr := fmt.Sprintf("%s:%d", ip, port)
conn, err := net.DialTimeout("tcp", addr, timeout)
if err != nil {
return fmt.Errorf("cannot connect to local service %s: %v", addr, err)
}
conn.Close()
return nil
}