1

我有一个由 py​​thon 和烧瓶实现的休息服务器。并实现一个api来重启ntpd
代码 test_flask.py:

from flask import Flask
import subprocess
import logging
import sys

app = Flask(__name__)


def run_shell_cmd(cmd):
    logging.info("run cmd: %s", cmd)
    try:
        rc = subprocess.call(cmd, shell=True)
        if rc != 0:
            logging.error("Fail to run %s , rc: %s" % (cmd, rc))
    except OSError as e:
        logging.error("Fail to run cmd: %s" % e)
    return rc

@app.route("/restart_ntpd")
def restart():
    run_shell_cmd("service ntpd restart")
    return "Success!"

if __name__ == "__main__":
    LOG_FORMAT = '%(asctime)s, %(levelname)s, %(filename)s:%(lineno)d, %(message)s'
    logging.basicConfig(
        format=LOG_FORMAT,
        level=logging.INFO,
        stream=sys.stdout,
    )
    app.run()

然后我操作如下:

  1. 启动烧瓶服务器:python test_flask.py
  2. curl " http://localhost:5000/restart_ntpd。然后 ntpd 重新启动并返回 "success"
  3. 停止烧瓶服务器:只需使用 Ctrl+c 停止
  4. 再次启动烧瓶服务器,它会引发异常:

    socket.error:[Errno 98] 地址已在使用中。

  5. 使用sh $ netstat -ntlp | grep 5000,端口被ntpd

我认为默认情况下ntpd将使用端口 123。在我的场景中,为什么端口 5000被强制执行ntpd?是烧瓶的问题吗?

4

1 回答 1

1

ntpd不是在侦听 TCP 端口 5000 本身,而是它正在运行的环境 - 进程。

该进程是您的 Flask 服务器进程的子进程,它打开一个侦听 TCP 端口 5000 的套接字。

这个套接字是在子进程中继承的,由于该ntpd进程是一个长时间运行的进程,它会继续使用它从你那里继承的套接字运行,占用5000端口。

检查Python BaseHTTPServer 被杀,但端口仍然被占用怎么办?关于如何防止子进程继承套接字。

当然,首先你得想办法自定义Flask启动服务器的方式。

于 2016-01-25T09:17:42.887 回答