gpt4 book ai didi

sockets - 转到 Unix 域套接字 : bind address already in use

转载 作者:IT王子 更新时间:2023-10-29 02:21:59 25 4
gpt4 key购买 nike

我有以下服务器代码,它通过 unix 域套接字进行监听

package main

import (
"log"
"net"
"os"
"os/signal"
"syscall"
)

func echoServer(c net.Conn) {
for {
buf := make([]byte, 512)
nr, err := c.Read(buf)
if err != nil {
return
}

data := buf[0:nr]
println("Server got:", string(data))
_, err = c.Write(data)
if err != nil {
log.Fatal("Writing client error: ", err)
}
}
}

func main() {
log.Println("Starting echo server")
ln, err := net.Listen("unix", "/tmp/go.sock")
if err != nil {
log.Fatal("Listen error: ", err)
}

sigc := make(chan os.Signal, 1)
signal.Notify(sigc, os.Interrupt, syscall.SIGTERM)
go func(ln net.Listener, c chan os.Signal) {
sig := <-c
log.Printf("Caught signal %s: shutting down.", sig)
ln.Close()
os.Exit(0)
}(ln, sigc)

for {
fd, err := ln.Accept()
if err != nil {
log.Fatal("Accept error: ", err)
}

go echoServer(fd)
}
}

当我使用 Ctrl+C 关闭它时,信号被捕获并且套接字被关闭。当我重新运行程序时,一切正常。

但是,如果正在运行的进程突然被终止,并且程序重新启动,则监听失败并显示错误 Listen error: listen unix/tmp/go.sock: bind: address already in use

如何优雅地处理这个问题?

我问这个的原因是:我知道突然杀死不是正常的方法,但是我的程序应该作为守护进程自动启动,如果我的守护进程重新启动,我希望能够再次监听套接字没有这个错误。

这也可能是因为先前的实例正在运行,据我所知。这里的问题是如何以编程方式在 Go 中识别并处理这种情况。正如答案中指出的那样 here ,可以在 C 程序中使用 SO_REUSEADDR。围棋有这种可能吗?另外,C 程序如何处理这个多实例问题。

最佳答案

您需要捕获信号并进行清理;一些示例代码:

func HandleSIGINTKILL() chan os.Signal {
sig := make(chan os.Signal, 1)

signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)

return sig
}

...
go func() {
<-HandleSIGINTKILL()

log.Info("Received termination signal")
// Cleanup code here

os.Exit(0)
}()

如果您kill -9 进程,这当然不起作用;您将需要手动移除套接字(或让您的初始化系统为您完成)。

关于sockets - 转到 Unix 域套接字 : bind address already in use,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43962818/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com