python3基于tonado搭建http服务

通过python3的tornado框架进行图片传输

目录

  • 通过python3的tornado框架进行图片传输
    • 先上完整代码
      • 服务端
      • 客户端
    • 代码使用
      • 客户端
      • 服务端

先上完整代码

服务端

import traceback
from io import BytesIO

import tornado
import tornado.ioloop
import tornado.web
from tornado.escape import json_encode
from PIL import Image
import pickle
from base64 import b64encode
import importlib,sys
importlib.reload(sys)

class Handler(tornado.web.RequestHandler):

    def post(self):
        result = {}
        content = self.request.arguments["content"][0]
        if content is None:
            result["msg"] = "no content"
        else:
            byte_array, msg = self.content_process(content)
            result["image"] = byte_array
            result["msg"] = msg
        self.write(json_encode(result))

    def content_process(self, image_content):
        try:
            content = pickle.loads(image_content)
            image = Image.open(BytesIO(content))
            image.save("./server.png")
            image = image.rotate(90)
            
            byte_array = BytesIO()
            image.save(byte_array, format='PNG')
            byte_array = byte_array.getvalue()
            byte_array = b64encode(byte_array).decode('utf-8')
            return byte_array, "sucess"
        
        except Exception as e:
            print(traceback.format_exc())
            return str(e), "wrong"

class ImageServer(object):

    def __init__(self, port, server_address):
        self.port = port
        self.address = server_address

    def process(self):
        app = tornado.web.Application([(r"/image_server?", Handler)], )
        app.listen(self.port, address=self.address)
        tornado.ioloop.IOLoop.current().start()

if __name__ == "__main__":
    server_port = "8080"
    server_address = "192.168.10.1"
    server = ImageServer(server_port, server_address)
    print("begin server")
    server.process()

客户端

import json
import urllib
import requests
import pickle
import urllib.request
from PIL import Image
from io import BytesIO
from base64 import b64decode

def post(server_url, params):
    data = urllib.parse.urlencode(params).encode('utf-8')
    request = urllib.request.Request(server_url, data)
    return json.loads(urllib.request.urlopen(request, timeout=100).read())

def local_image(server_url, image_path):
    r_file = open(image_path, "rb")
    content = pickle.dumps(r_file.read())
    params = {"content": content}

    json_return = post(server_url, params)
    msg = json_return["msg"]

    image_bytes = b64decode(json_return["image"])
    image = Image.open(BytesIO(image_bytes))
    image.save("./user.png")

if __name__ == "__main__":
    # url = "http://localhost:8080/image_server?"
    url = "http://192.168.10.1:8080/image_server?"

    file_path = "/home/yangwn/code/server_test/46.jpg"
    local_image(url, file_path)

代码使用

代码只要修改了图片pathurl就能直接用

客户端

在主函数main中的url要适配你服务端的url,如果不知道输入什么地址,就用注释的那一行,也就是localhost,注意端口号是必要的
在进入local_image函数后,将图片数据转成字节流,并打包成dict字典的形式传到post函数
post函数里面继续把字典转成字节流,随后就上传到服务端,并等待服务端返回
接着将返回值接收,我这里返回的是一张图片和一个状态(msg),把返回的图片字节流进行转换后用BytesIO打开即可

服务端

如果前面的客户端你想要用localhost,那就把address设置为None
图片数据的传输方式都一样
就是在post中写数据的时候还用了json_encode,所以把图片用代码先转成字符了

byte_array = BytesIO()
image.save(byte_array, format='PNG')
byte_array = byte_array1.getvalue()
byte_array = b64encode(byte_array).decode('utf-8')

小结:很简单的一个传输,但是找了很久好像没有可以直接拿来用的代码,就自己找找资料写了个。这个只是刚好能用的版本,中间可能还有什么bug就你们自己调整了