有: 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/