python使用udp分包传输图像数据

客户端

import socket
import time
import threading
import pyautogui
import cv2
import numpy as np
#发送截屏图像
def send_msg():
    while True:
        # 起始坐标 0  0  截取一张 X宽  y 高的图像  返回数据类型PIL.Image.Image image mode=RGB
        pil_im = pyautogui.screenshot(region=(0, 0, pic_width, pic_height))
        # 将PIL.Image.Image 转换为  numpy.ndarray 类型的数组 可以 使用cv2.imshow('a', np_img)显示
        np_img = cv2.cvtColor(np.asarray(pil_im),cv2.COLOR_RGB2BGR)
        # 将图片编码  send_data_num为0-255数字
        res, send_data_num = cv2.imencode('.jpg', np_img, (cv2.IMWRITE_JPEG_QUALITY, 50))
        send_data = send_data_num.tobytes()  # 编码转换为 字节流
        send_data_len = len(send_data)  # 获取数据长度
        i = send_data_len // package_len  # 分包发送 包的个数
        j = send_data_len % package_len  # 剩余字节的个数
        client.sendto(begin_flag, host)  # 发送起始标志
        for n in range(0, i):  # 分包发送
            client.sendto(send_data[n * package_len:package_len * (n + 1)], host)
        client.sendto(send_data[-j:], host)  # 发送剩余字节
        client.sendto(end_flag, host)  # 发送结束标志
        # time.sleep(10)
#接受数据
def recv_data():
    while True:
        back_data = client.recv(1024).decode()
        print('收到服务器端的信息:' + back_data)

#截屏的大小
pic_width = 800
pic_height = 600
begin_flag = b'Framebegin:'   # 一张图像起始标志
end_flag = b'Frameovers:'     #  一张图片结束标志
package_len = 1024  # 包的大小
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
host = ('121.4.99.98', 8081)
client.sendto("Client Msg".encode(), host)  # 要先向服务器发送一条数据 建立连接  连接不上服务器 也不报错
t0 = threading.Thread(target=recv_data)
t0.start()
t1 = threading.Thread(target=send_msg)
t1.start()


服务器端

import socket
import threading
import time
import pyautogui
import cv2
import numpy as np
# 向所有客户端发送数据
def send_msg():
    while True:
        for client in client_list:
            server.sendto("Server Msg!".encode(), client)
        time.sleep(2)
#接收客户端的数据
def recv_data():
    img_bytes = b''  # 保存一张图像
    while True:
        data, addr = server.recvfrom(package_len)
        if not(addr in client_list):  # 将客户端添加进列表
            client_list.append(addr)
        if data:  # 判断data不为空
            if data == begin_flag:  # 如果图像数据包来了
                while True:  # 开启一个循环接受数据
                    data, addr = server.recvfrom(package_len)
                    # 如果结束包来了  则说明一张图像数据完毕  udp 结束包是单独过来的 tcp 结束包会和最后一个图像数据包混在一起
                    if data == end_flag:
                        break  # 跳出接收这样图像的循环
                    img_bytes = img_bytes + data  # 如果不是结束包 则将数据添加到变量 继续循环
                # 显示图片
                np_data = np.frombuffer(img_bytes, dtype="uint8")
                r_img = cv2.imdecode(np_data, cv2.IMREAD_COLOR)
                r_img = r_img.reshape(pic_height, pic_width, 3)  # 会报错
                cv2.imshow("title", r_img)
                img_bytes = b''
                if cv2.waitKey(1) & 0xFF == ord('q'):
                    break
            else:
                print(data)
    cv2.destroyAllWindows()


#收到图像的大小
pic_width = 800
pic_height = 600
begin_flag = b'Framebegin:'   # 一张图像起始标志
end_flag = b'Frameovers:'     #  一张图片结束标志
package_len = 1024            # 一帧数据长度
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
host = ('10.0.4.11', 8081)
server.bind(host)
client_list = []  #保存 客户端addr 的列表
t0 = threading.Thread(target=recv_data)
t0.start()
t1 = threading.Thread(target=send_msg)
t1.start()

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值