Tornado和subprocess实现和外部程序通信
admin
2023-07-03 21:25:07
0

  主要涉及subprocess的使用,简单点,直接上代码吧,只是做一下记录。

  import tornado.ioloop, os, random

  import urllib, time

  import tornado.web

  import tornado.httpserver

  import tornado.options

  import subprocess

  from tornado.options import options, define

  from tornado.web import url, RequestHandler, MissingArgumentError

  from tornado.escape import json_encode

  ##

  # 功能:文件上传、代码提交、执行代码、停止代码

  #

  # 路由:ip:8000/

  # 演示功能:打开上传文件或者上传文件的浏览器界面,点及上传或者提交代码

  # 路由:ip:8000/upload

  # post上传文件的接口,将所选的文件中的内容转储到服务器中的/tmp/new_code.py文件中

  # 路由:ip:8000/send

  # post提交代码的接口,代码作为字符串形式提交

  # 路由:ip:8000/run/start

  # 启动服务器中文件名为new_code.py的代码文件,新建线程执行

  # 路由:ip:8000/run/stop

  # 停止服务器中文件名为new_code.py所开启的线程

  ##

  # 设置服务的端口

  define("port", default=8000, type=int, help="run server on the given port.")

  # 静态资源配置

  settings = {

  "static_path": os.path.join(os.path.dirname(__file__), "static"),

  "template_path": os.path.join(os.path.dirname(__file__), "views"),

  }

  ##

  # 设置允许跨域请求的base类

  class BaseHandler(tornado.web.RequestHandler):

  def set_default_headers(self):

  self.set_header("Access-Control-Allow-Origin", "*");

  self.set_header("Access-Control-Allow-Headers", "*");

  self.set_header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); #请求允许的方法

  self.set_header("Access-Control-Max-Age", "3600");

  #处理OPTIONS请求

  def options(self):

  #返回方法1

  #self.set_status(204)

  #self.finish()

  #返回方法2

  self.write('{"errorCode":"00","errorMessage","success"}')

  ##

  # localhost:8000/ 打开浏览器输入,

  class MainHandler(BaseHandler):

  def get(self):

  self.write('

  self.write('') #

  #

  # 文件上传的类,使用post发送

  class UploadHandler(BaseHandler):

  def get(self):

  # a3_url = self.reverse_url("a3_url")

  # self.write('this is a3' % a3_url)

  self.write("get code:

  ")

  def post(self):

  files = self.request.files["fff"]

  if files:

  pyf = files[0]["body"]

  # pyfname = files[0]["filename"]

  # self.write(pyfname)

  with open("/tmp/new_code.py", 'wb+') as up:

  up.write(pyf)

  self.write("OK")

  else:

  self.write("Error!")

  # 发送代码字符串的类(带隐式格式)

  class SendHandler(BaseHandler):

  # 用URL的get的方式发送

  def get(self):

  code = self.get_argument("code")

  if code:

  with open("/tmp/new_code.py", 'w+') as up:

  up.write(code)

  else:

  self.write("参数为空!")

  # 用form表单或者ajax等的post加密方式发送

  def post(self):

  # URL编码

  code = urllib.parse.quote(self.request.arguments["code"][0].decode("UTF-8"))

  if code:

  # name = str(random.randint(0,1000))+".py"

  with open("/tmp/new_code.py", 'w+') as up:

  # URL解码

  up.write(urllib.parse.unquote(code))

  # 回显到控制台

  with open("/tmp/new_code.py", 'r') as r:

  rs = r.readlines();

  for x in rs:

  print(x, end="")

  else:

  self.write("参数为空!")

  # 存放线程对象

  class G:

  p = None

  ##

  # 执行代码文件的类

  class SsHandler(BaseHandler):

  def get(self, cmd):

  '''

  cmd: 接收前端的正则表达式字符串

  '''

  print("Command:%s" % cmd)

  if cmd == 'start':无锡妇科医院排行 http://www.0510bhyy.com/

  # 将文件名修改

  G.p = subprocess.Popen(["python","/tmp/new_code.py"], shell=False, stdout=subprocess.PIPE, stderr = subprocess.PIPE)

  # this is a test server used to see whether it is running or not

  # print("tornado l_server running at http://localhost:8001/a1")

  print(type(G.p))

  print(G.p)

  # 会阻塞

  # returncode = G.p.wait()

  # print(returncode)

  elif cmd == 'stop':

  if G.p is not None:

  poll = G.p.poll() #获取子进程的状态

  if poll==0:

  # print(G.p.stdout.read())

  # print(G.p.stderr.read())

  print("程序执行完毕!不需要手动结束!")

  elif poll is None:

  print("程序正在执行!马上退出...")

  # 获取子进程的pid

  pid = G.p.pid

  print("pid: {}".format(pid))

  # 杀死进程

  G.p.kill()

  print("killed.")

  else:

  print("状态码:{}".format(poll))

  print("程序异常退出!")

  else:

  print("p is nothing")

  else:

  print("Command is not right!")

  print("Done!")

  # 没用

  def post(self):

  self.write("post-StartHandler")

  # 定义路由设置

  def make_app():

  return tornado.web.Application([

  (r"/", MainHandler),

  # (r"/get", ItcastHandler, {"subject":"sub"}),

  (r"/upload", UploadHandler),

  (r"/send", SendHandler),

  (r"/run/(\w*)", SsHandler),

  (r"/(apple-touch-icon\.png)", tornado.web.StaticFileHandler,

  dict(path=settings['static_path'])),

  ], **settings)

  ##

  # main函数入口

  if __name__ == "__main__":

  tornado.options.parse_command_line()

  app = make_app()

  app.listen(options.port)

  print("tornado server running at http://localhost:8000")

  tornado.ioloop.IOLoop.current().start()


相关内容

热门资讯

内蒙古包头:首批投运1000辆... 新华社5月31日消息,近日,我国自主研发的氢能两轮车在内蒙古自治区包头市面向公众投入运营,首批将在公...
缅甸边境发生爆炸,云南群众目击... 5月31日,缅甸掸邦北部南坎镇发生一起爆炸事故,已导致多人伤亡,多处民宅、房屋遭到严重损毁。经初步调...
大湾区打出智造新名片,高域首台... 近日,在广州黄埔区的智能制造产业园内,一架白色多旋翼飞行器缓缓驶出生产线,标志着高域(GOVY)这家...
VR眼镜与元宇宙:沉浸式体验会... VR眼镜与元宇宙:沉浸式体验会不会导致“魂不守舍”?虚拟现实对精神能量的消耗 杨明德/文 朋友们好,...
张凌赫粉丝挤爆玻璃门、活动临时... 5月31日,张凌赫原定在广西南宁万象城出席品牌活动,大批粉丝早早前往商场排队等候。现场人潮涌动,人群...
5月31日“蓝月亮”上线,还是... 据新华社:5月31日,农历四月十五,一轮满月将现身夜空。这轮满月有些特别,它是本月第二次满月,同时它...
中国的刀产量,究竟有多恐怖? 中年男人在短视频平台最爱看啥?小姐姐跳舞?那你可就想错了——锻刀大赛才是中年男人真正的“减速带”。在...
花费半生积蓄,农村自建房热背后 今年以来,在安徽安庆望江县做外墙漆生意的徐仙琴越来越忙碌了,她和员工们每天奔波在县城的各个村庄里,找...
黎以冲突再升级对中东地区影响几... 从当前的局势来看,黎以双方博弈已陷入谈判停滞、战火升级的恶性循环,地区冲突风险持续走高。根据以军发布...
易事达取得载带冷却定型装置专利... 国家知识产权局信息显示,浙江易事达电子材料有限公司取得一项名为“一种载带冷却定型装置”的专利,授权公...