c++ - 服务重启后套接字未释放

标签 c++ linux sockets service restart

有: A:持有开放套接字的程序 B:看门狗脚本作为服务运行:

while true
do
        if [ -z "`pidofproc $1`" ]; then
                $1;
            chrt -f -p 40 `pidofproc $1`
                sleep 8
        fi;
        sleep 2
done

服务启动时——看门狗启动
当服务停止时 - 看门狗和程序被杀死 (killall)。

现在程序要升级自己,所以调用system( "upgrade.sh");

升级.sh:

/sbin/service watchdog stop

.... install upgrade  .....

exec /sbin/service watchdog start &

升级成功执行,但程序启动时 - 无法打开套接字(已在使用中) - 出现此错误 - 程序退出(由看门狗重新启动)。

lsof -i 显示端口上的三个程序:

watchdog

program

sleep

程序和 sleep pids 总是改变(即退出/重启行为)

看门狗 pid 持久化。

我尝试用

替换system(...)

if(!fork()) exec(...) ,但同样的问题仍然存在。

最佳答案

根据关闭后重新启动的速度,套接字将徘徊。默认情况下,Linux 会在套接字被释放后(通过 close() 或进程终止时)将套接字标记为正在使用,以确保传入的连接尝试或正在使​​用的数据由于网络延迟而迟到的应用不会出现错误。

这必须在应用程序内部修复。需要设置 SO_REUSEADDR sockopt。根据 socket(7) 的联机帮助页:

Indicates that the rules used in validating addresses supplied in a bind(2) call should allow reuse of local addresses. For AF_INET sockets this means that a socket may bind, except when there is an active listening socket bound to the address. When the listening socket is bound to INADDR_ANY with a specific port then it is not possible to bind to this port for any local address. Argument is an integer boolean flag.

这必须在创建套接字后使用 setsockopt 进行设置。

关于c++ - 服务重启后套接字未释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13864247/

相关文章:

c++ - stringstream 删除前导 0

linux - Linux 有没有好的 "OCaml Browser"工具?

c# - 将 block 与套接字一起使用

c - 基于 fork 的服务器是否可以进行客户端-客户端通信?

linux - 如何查找特定格式的数字并过滤掉特定范围的值?

android - gstreamer可以播放使用下面这个客户端代码发送的媒体内容吗?

c++ - 覆盖基类无法正常工作

c++ - 代码行在两行之后不起作用

c++ - 如何定义具有异构值类型的 QHash?

c++ - 编译程序时的错误信息