grpc图片传输 python实现

Grpc的安装和原理,见官网:https://grpc.io/

由于我的目的是不断地从客户端传输图片到服务器端,然后服务器在每次收到图片后返回结果,所以我用的是:

  • 客户端流式RPC,客户端再次使用提供的流写入一系列消息并将其发送到服务器。一旦客户端写完消息,它就等待服务器读取它们并返回它的响应。

下面是我的proto文件,命名为:upload.proto:

syntax = 'proto3';

service Upload {
    rpc Fileup(stream Tdata) returns (Tdata) {}
}

message Tdata {
    string data = 1;
    int64 size = 2;
    string name = 3;
}

 从.proto服务定义生成gRPC客户端和服务器接口:

$ python -m grpc_tools.protoc -I../../protos --python_out=. --grpc_python_out=. ../../protos/upload.proto

然后就会得到:upload_pb2.py 和 upload_pb2_grpc.py (自动生成的)

接下去实现客户端和服务器端的代码:

客户端:

import threading
import grpc
import time
import codecs
from pprint import pprint
from tqdm import tqdm
import base64
import os
import sys
import argparse
from proto import upload_pb2_grpc
from proto import upload_pb2
import time
import numpy as np

def getfile(path,chunksize):
    readsize = 0
    filesize = sys.getsizeof(path)
    data =[]
    if filesize<chunksize:
        path=bytes(path)
        data.append(base64.b64encode(path))
    return data


def run(tf_file, path, ip):
    channel = grpc.insecure_channel('{}:50053'.format(ip))
    stub = upload_pb2_grpc.UploadStub(channel)
    def stream():
        for tf in tf_file:
            yield upload_pb2.Tdata(data=tf, size=len(tf_file), name=path)

    response = stub.Fileup(stream())
    # print("received: " + response.data)
    # 我这里返回的是字符串,接下去转换成数组
    stri = response.data
    list = stri.split(" ")
    for i in range(len(list)):
        list[i] = np.fromstring(list[i], dtype=int, sep=',')
    list = np.array(list)
    return list

服务器端:

import threading
import grpc
from proto import upload_pb2_grpc
from proto import upload_pb2
import time
from concurrent import futures
import base64
from pprint import pprint
import os
import re
import cv2
import numpy as np

import PIL

class Upload(upload_pb2_grpc.UploadServicer):

    def Fileup(self, request_iterator, context):
        i=0
        file_exist = False
        while 1:
            for Tdata in request_iterator:
                out_ite = Tdata
                print(type(out_ite))
                binary_data = base64.b64decode(out_ite.data)
                if (os.path.exists(out_ite.name) and i == 0) or file_exist:
                    if i == 0:
                        print('{} already exists,So no copy this file.'.format(out_ite.name))
                    file_exist = True
                    pass
                else:
                    if re.search('/', out_ite.name):
                        os.makedirs(os.path.dirname(out_ite.name), exist_ok=True)
                        file_name = out_ite.name
                    else:
                        file_name = out_ite.name
                    # 这里我传输的图片是:640*480的三通道彩色图
                    image = np.fromstring(binary_data, np.uint8).reshape( 480, 640, 3 )
                    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
                    cv2.imwrite(file_name, image)

                i += 1
                if i == out_ite.size and not file_exist:
                    print('complete! {} '.format(out_ite.name))
                    print(time.time())
                # 事实上要返回的数据结果,是通过图像处理得到的,这里只是举例
                list1 = [[100, 200, 300, 400], [12, 120, 133, 140]]
                list1 = np.array(list1)
                stri = ""
                # 将数组转换成字符串
                for i in range(len(list1)):
                    for j in range(len(list1[i])):
                        stri += "".join(str(list1[i][j]))
                        if (j < (len(list1[i]) - 1)):
                            stri += ","
                    if(i<(len(list1)-1)):
                        stri += " "
                return upload_pb2.Tdata(data=stri, size=out_ite.size, name=out_ite.name)

upload.py:(

import argparse
import client
import server
import threading
import grpc
from concurrent import futures
import time
import os
import re
import sys
from proto import upload_pb2_grpc
from proto import upload_pb2
import numpy as np

# sys.path.append('D:/python/apple-picker/pyuploader') 

def server():  # 服务器端
    fserver = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    upload_pb2_grpc.add_UploadServicer_to_server(
        server.Upload(), fserver)

    fserver.add_insecure_port('[::]:50053')
    fserver.start()
    print('file waiting...')
    while 1:
        time.sleep(1)


def client_run(read_path, send_path, ip): # 客户端
    chunksize = 1000000
    tf_file = client.getfile(read_path, chunksize)
    lst_box = client.run(tf_file, send_path, ip)
    return lst_box


def client_all_image(paths,send_path,ip):
    img = paths[0]
    filesize = sys.getsizeof(img)
    lst_box = client_run(img, send_path, ip)
    return lst_box
   

开启客户端:

def send_file(out, lst_box, ip, close_camera):
    """利用Grpc和视觉系统的通信,传输图片"""
    # 这里的out是从相机直接得到的图片
    index = 0
    while close_camera[0] == 1:
        image_name = "ZImage_" + str(index) + ".jpg"
        lst_box[0] = client_all_image(out, image_name, ip[0])
        lst_box[1] = time.time()
        index += 1
        time.sleep(5) # 隔5s传一次

服务器端:

直接调用 server方法即可。

这里我传输的是直接从相机得到的图片,如果是传输图片文件需要修改文件读写部分的代码。

祝顺利 :)

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值