python udp传输图像与文件

57 篇文章 530 订阅 ¥19.90 ¥99.00
这篇博客介绍了如何利用Python的UDP协议进行图像和文件的传输。首先讲解了UDP的工作原理,包括服务器如何绑定IP和端口,以及客户端如何直接发送数据。内容强调了数据需转换为二进制流,利用opencv处理图像,并通过多线程实现文件的发送。
摘要由CSDN通过智能技术生成

感谢这位作者

https://blog.csdn.net/qq_36852276/article/details/90761122

1.理论基础
首先要了解UDP的工作模式
对于服务器,首先绑定IP和端口,本机测试的时候可以使用127.0.0.1是本机的专有IP,端口号 大于1024的是自定义的,所以用大于1024的端口号,然后接收客户端数据,处理,返回对于客户端,UDP不用建立连接,只管发送不管接收到没有,所以可以直接对服务器的IP地址和端口号发送信息,然后等待应答。
注意传输的数据是二进制流数据,所以要找方法把需要传输的数据编码成二进制码流,传过去之后再解码即可,这里我用到了opencv读取图片成numpy的array格式,然后编码,传输,最后接到之后再解码。

这里采用多个线程来完成图片与文件的获取

2 代码实现

#udp_sever.py
# -*- coding: utf-8 -*-
import socket
import cv2
import numpy as np
import struct
import threading
import json
#设置IP地址、两个服务器端口号
dest_ip = '127.0.0.1'
img_port = 9999
msg_port = 6666

#服务器1的处理、应答函数,接收图片、显示、应答
def receive_img(rec_img):
    while True:
        # 接收数据:
        fhead_size = struct.calcsize('l')
        buf,addr = rec_img.recvfrom(fhead_size)
        if buf:
            data_size = struct.unpack('l',buf)[0]
            print(data_size)
        recvd_size = 0
        data_total = b''
        while not recvd_size == data_size:
            if data_size -recvd_size >1024:
                data,addr = rec_img.recvfrom(1024)
                recvd_size += len(data)
            else:
                data,addr = rec_img.recvfrom(1024)
                recvd_size = data_size  
            data_total += data
#       data, addr = rec_img.recvfrom(400000)
        print('Received')
#       reply = 'Hello, %s!' % data.decode('utf-8')
#       rec_img.sendto(reply.encode('utf-8'), addr)

        nparr = np.fromstring(data_total, np.uint8)
        img_decode = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
        cv2.imshow('result',img_decode)
        cv2.waitKey(100)
        reply = "get message!!!"
        rec_img.sendto(reply.encode('utf-8'), addr)
#        cv2.destroyAllWindows()

#服务器2函数,接收消息、输出、应答
def receive_msg(rec_msg):
    while True:
        msg_data ,msg_addr = rec_msg.recvfrom(1024)
        msg_str = msg_data.decode('utf-8')
        msg = json.loads(msg_str)
        print(msg)
        reply = 'get the msg'
        rec_msg.sendto(reply.encode('utf-8'),msg_addr)
    rec_msg.close()

#主函数 创建服务器、绑定端口、创建运行两个进程、调用上面两个函数
def main():
    #创建套接字
    rec_img = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    rec_msg = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    #绑定本地地址端口
    rec_img.bind((dest_ip, img_port))
    rec_msg.bind((dest_ip, msg_port))
    #创建进程
    t_recimg = threading.Thread(target=receive_img, args=(rec_img,))
    t_recmsg = threading.Thread(target=receive_msg, args=(rec_msg,))
    #开始进程
    t_recimg.start()
    t_recmsg.start()
    print('程序正常运行!!!')
if __name__ == '__main__':
    main()

客户端1发送视频

udp_client_1.py
# -*- coding: utf-8 -*-
import socket
import cv2
import numpy as np
import struct

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
cap = cv2.VideoCapture(0)
#cap.set(3,320)
#cap.set(4,240)
while True:
    
    if cap.isOpened():
        flag, img = cap.read()
#        img = cv2.imread('/home/xbw/jupyter_notebook/0.jpg')
        img_encode = cv2.imencode('.jpg', img)[1]
        data_encode = np.array(img_encode)
        data = data_encode.tostring()
        #定义文件头
        fhead = struct.pack('l',len(data))
        # 发送文件头、数据:
        s.sendto(fhead,('127.0.0.1', 9999))
        for i in range(len(data)//1024+1):
            if 1024*(i+1)>len(data):
    	        s.sendto(data[1024*i:], ('127.0.0.1', 9999))
            else:
                s.sendto(data[1024*i:1024*(i+1)], ('127.0.0.1', 9999))
        # 接收应答:
        cv2.waitKey(1)
        print(s.recv(1024).decode('utf-8'))

s.close()

接下来文件的发送客户端

#udp_client_2.py
import socket
import cv2
import numpy as np
import struct
import json
import time
#定义套接字
send_msg = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#设置目标IP地址、端口号
target_ip = '127.0.0.1'
target_port = 6666
#发送数据,等待应答
while True:
    data = [0,0,0,1]
    data_str = json.dumps(data)
    send_msg.sendto(data_str.encode(),(target_ip,target_port))
    time.sleep(0.01)
    print(send_msg.recv(1024).decode('utf-8'))

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值