gpt4 book ai didi

python - 在 Python 中重启 HTTP 服务器的正确方法

转载 作者:可可西里 更新时间:2023-11-01 16:44:14 26 4
gpt4 key购买 nike

我正在使用下面的代码片段在 Python 中编写一个 HTTP 服务器。服务器运行良好,直到发生某些 IOError 导致它重新启动。我的重启处理有问题,因为服务器启动正常但之后不接受任何请求。

这段代码有什么问题吗?

#!/bin/python
from BaseHTTPServer import HTTPServer
import json
import config
import time
import socket
from SimpleHTTPServer import SimpleHTTPRequestHandler
from SocketServer import BaseServer


class MyHandler(SimpleHTTPRequestHandler):
def parseArgs(self):
args = {}
try:
config.logging.info(self.path)
args_list = self.path.split("?")[1].split("&")
for entry in args_list:
args[entry.split("=")[0]] = entry.split("=")[1]
except IndexError:
pass
return args

def do_GET(self):
try:
response = {}
args = self.parseArgs()
config.logging.debug("Handle the request")
self._handle_request(args, response)
config.logging.debug("Write the header back to the client.")
self.send_response(200)
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Content-Type:', 'application/json; charset=UTF-8')
self.end_headers()
config.logging.debug("Finish writing the header and start writing JSON response.")
json_encoded = json.dumps(response)
config.logging.debug(json_encoded)
self.wfile.write(json_encoded)
config.logging.debug("JSON Response written successfully.")
except Exception as e:
config.logging.exception('Exception occurs when writing back the response.')
return

def _handle_request(self, args, response):
try:
response["sysTime"] = long(round(time.time() * 1000))
if not "cmd" in args:
response["message"] = "Error: No command provided."
else:
response["message"] = args['cmd']
except Exception as e:
response["message"] = "Error: Exception occurs (check logs)."
config.logging.exception('Exception occurs when handling request.')

def do_POST(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write("Nothing here :( ")

def main():
while True:
try:
httpd = HTTPServer(('', config.listening_port), MyHandler)
sa = httpd.socket.getsockname()
msg = "Serving HTTP on " + sa[0] + " port " + str(sa[1]) + "..."
print msg
config.logging.info(msg)
httpd.serve_forever()
except KeyboardInterrupt:
print '^C received, shutting down server'
config.logging.info('^C received, shutting down server')
httpd.socket.close()
break
except Exception as e:
httpd.shutdown()
httpd.socket.close()
print "Error occurs. Retry in 5 seconds"
config.logging.exception('Exception occurs. Retry in 5 seconds.')
time.sleep(5)

if __name__ == '__main__':
main()

抱歉缺少模块配置。

import logging

# global variables
listening_port = 9001
logging.basicConfig(filename='error.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')

运行它的一个 url 是 http://localhost:9001/?cmd=some_command。只需在服务器启动后将其粘贴到任何浏览器即可。

编辑:

我想这与 KVM 或它在我公司机器上的设置方式有关。由于我的服务器运行在只能通过 ssh 访问的 KVM 上,每次我退出 ssh session 时,调用上面的 url 命令(在 chrome 中),等到 chrome 通知未连接,返回到 ssh session ,调用 url再次命令,错误发生。

我将调试消息放在 self.send_response(200) 中 do_GET() 的写入响应之间。当异常发生时,这是我得到的痕迹。我想这与 log_message 中的 sys.stderr.write 有关。

11/23/2012 10:58:29 AM - INFO - Handle the request
11/23/2012 10:58:29 AM - INFO - /?cmd=get_info&uid=pp
11/23/2012 10:58:29 AM - INFO - Write the header back to the client.
11/23/2012 10:58:29 AM - ERROR - Exception occurs when writing back the response.
Traceback (most recent call last):
File "service.py", line 57, in do_GET
self.send_response(200)
File "/usr/lib/python2.7/BaseHTTPServer.py", line 385, in send_response
self.log_request(code)
File "/usr/lib/python2.7/BaseHTTPServer.py", line 422, in log_request
self.requestline, str(code), str(size))
File "/usr/lib/python2.7/BaseHTTPServer.py", line 458, in log_message
format%args))
IOError: [Errno 5] Input/output error

编辑:

当我重写 log_message() 什么也不做时,问题就消失了。我知道这只会隐藏问题,但至少它暂时对我有用。

最佳答案

sys.stderr 将消息写入标准输出,通常是您启动程序的 shell 控制台。因此,如果 shell 控制台关闭,sys.stderr.writes 将引发 IO 错误。

所以问题的根本原因是 log_message() 函数中的 sys.stderr.write 试图将消息写入您最初启动 python 程序的 ssh shell 控制台(标准输出),所以如果您保留ssh session 还活着,这个问题就不会发生。但是如果你退出原来的 ssh session ,shell 控制台被关闭,然后 sys.stderr.write 就不能向原来的控制台写入消息,然后 IO 错误发生...... log_message 通常写这样的东西:

127.0.0.1 - - [01/Dec/2015 20:16:32] "GET / HTTP/1.1" 200 -

因此解决方案是运行 python 脚本并将标准输出重定向到/dev/null,如下所示:

python your_script.py > /dev/null 2>&1 &

帮助它。

关于python - 在 Python 中重启 HTTP 服务器的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13497330/

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