Tornado和subprocess實現和外部程序通信

  主要涉及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()


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章