UDP通信传输图像、数据(基于python-socket)

先记录一个能实现的,基于base64进行编码传输;
但由于编解码大于传输整张图像的时间,所以准备直接传输。

不编码直接传输:

  • 直接可以 s.sendto(np_array,addr) ,对方接收的为bytes;
  • 采用 a = np.frombuffer(datas,dtype=np.uint8,offset=0),第三个参数表示舍弃前offset个;
  • 注意:需要设置np.set_printoptions(threshold=1e10),不然大的array转str的时候会直接省略号;
  • 发送的array过大,且需要解析;需要分包发,然后对方分包接收,解析,然后合并
  • (1)解析bytes:按字符解析;
  • (2)合并bytes,再转numpy: 新建datas = b'',然后每个包解析后取需要的bytes,然后+=就好了。注意:发送的时候image需要转换为uint8,不然默认为8byte,转化后才是一个数字对应一个byte。image = image.astype(np.uint8)
  • 11.24补充,对于丢包问题,采用多进程:进程1进行收取,put进queue中;进程2对数据进行queue.get(),这个的问题在于如果queue中存储太多,会累计延迟;所以需要定时清理queue。继续增加一个进程,一个列队;p1只进行判ip执行recvfrom,收到的包put到que1;p2只进行que1.get然后解析与拼接包,完整img就put到que2;p3进行que2.get然后进行图像处理。 注意: que.put时间可能比rece长。
  • 需要对Linux的socket的最大接收缓存进行设置,然后在代码中进行修改s.setsockopt(socket.SOL_SOCKET,socket.SO_RCVBUF,512*512*1024)

sysctl -a | grep rmem
修改配置文件:sudo gedit /etc/sysctl.conf
添加:
net.core.rmem_max = 51210241024 #设置512M
执行配置:sysctl -p

  • [ ]

base64编码传输
client


def socket_client(filepath,ip = '127.0.0.1:8888'):
    try:
        
        # 1、创建socket通信对象
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 2、使用正确的ip和端口去链接服务器
        s.connect((ip.split(':')[0],int(ip.split(':')[1])))

    except socket.error as msg:
        print(msg)
        sys.exit(1)

    # print (s.recv(1024))
    print('tcp 协议')

    BASE64  = 1
    recvData = None
    while 1:
        if os.path.isfile(filepath):
            img = cv2.imread(filepath,0)
            start_t = time.time()
            if BASE64:
                # #编码成base64
                # fp = open(filepath, 'rb')
                # imgData = base64.b64encode(fp.read())
                img_str = cv2.imencode('.jpg', img)[1].tostring()  # 将图片编码成流数据,放到内存缓存中,然后转化成string格式
                imgData = base64.b64encode(img_str) # 编码成base64
            else:
                #不编码
                imgData = img.tostring()
            s.send(imgData)
            print('send time:',(time.time() - start_t)*1000)
            # 接收服务器的响应(服务器回复的消息)
            recvData = s.recv(1024).decode('utf-8')
            # print('客户端收到服务器回复的消息:%s' % (recvData))
            end_t = time.time()
        # 4、关闭socket对象
        s.close()
        return "%.3f ms"%((end_t - start_t)*1000),recvData

def socket_client_udp(filepath,ip = '127.0.0.1:8888'):
    print('udp 协议')
    BASE64 = 1
    s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    if os.path.isfile(filepath):
        img = cv2.imread(filepath,0)
        start_t = time.time()
        if BASE64:
            img_str = cv2.imencode('.jpg', img)[1].tostring()  # 将图片编码成流数据,放到内存缓存中,然后转化成string格式
            imgData = base64.b64encode(img_str) # 编码成base64
        else:
            #不编码
            imgData = img.tostring()
        s.sendto(imgData,(ip.split(':')[0],int(ip.split(':')[1])))
        print('send time:%.6f ms'%((time.time() - start_t)*1000))
        recvData,addr = s.recvfrom(2048)
    end_t = time.time()
    s.close()
    return "%.3f ms"%((end_t - start_t)*1000),recvData.decode('utf-8')

server

def socket_service_tcp(model_path = 'epoch29.pth',ip = '127.0.0.1:8888'):
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind((ip.split(':')[0],int(ip.split(':')[1])))
        # s.bind(("127.0.0.1",8888))
        s.listen(5)
    except socket.error as msg:
        print(msg)
        sys.exit(1)
    TEST = ModelTest(model_path)
    print ("Waiting...")
    while 1:
        conn, addr = s.accept()
        t = threading.Thread(target=deal_data, args=(conn, addr,TEST))
        t.start()

def deal_data(conn, addr,TEST):
    print ('Accept new connection from {0}'.format(addr))
    BASE64 = 1
    while 1:
        if BASE64:
            data = conn.recv(5000)
            #base64编码
            data = base64.b64decode(data)
            nparr = np.frombuffer(data, dtype=np.uint8)
            cvImg = cv2.imdecode(nparr, cv2.IMREAD_GRAYSCALE) 
        else:
            data = conn.recv(40000)
            cvImg = np.fromstring(data,dtype=np.uint8)
            cvImg.shape = 200,200
            # print(cvImg.shape,cvImg)
        #deal img
        result = TEST.startPredict(cvImg)
        # 给socket服务器发送信息
        send_data = str(result)
        conn.send(send_data.encode('utf-8'))
        conn.close()
        break

def socket_service_udp(model_path = 'epoch29.pth',ip = '127.0.0.1:8888'):
    s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    s.bind((ip.split(':')[0],int(ip.split(':')[1])))
    TEST = ModelTest(model_path)
    BASE64 = 1
    while True:
        if BASE64:
            data,addr = s.recvfrom(5000)
            #base64编码
            data = base64.b64decode(data)
            nparr = np.frombuffer(data, dtype=np.uint8)
            cvImg = cv2.imdecode(nparr, cv2.IMREAD_GRAYSCALE) 

        else:
            data ,addr= s.recvfrom(40000)
            cvImg = np.fromstring(data,dtype=np.uint8)
            cvImg.shape = 200,200
        print ('Accept new connection from {0}'.format(addr))
        #deal img
        result = TEST.startPredict(cvImg)
        result = (str(result)).encode('utf-8')
        s.sendto(result,addr)
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值