视频监控笔记(五):Jetson Nano上通过Tkinter和Socket实现GUI文件传输

简介: 这篇文章介绍了如何使用Python的Tkinter和Socket在Jetson Nano上实现图形用户界面(GUI)的文件传输系统,包括服务器端和客户端,能够进行文件的发送和接收,并展示传输进度。

图片

bj.png
bj.png

服务器端

Server.py

# coding=utf-8

import cv2
import os
import json
import socket
import threading
#读取文件的最大数
max_len=1024
import tkinter.messagebox

def socket_server():
    # 端口号和IP地址
    remote_addr = ("192.168.80.129", 9999)

    # 绑定IP地址和端口号PORT
    socket_Server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    socket_Server.bind(remote_addr)

    # 监听
    socket_Server.listen()
    print('正在监听来自客户端的消息......')
    return socket_Server

def Server_Recv_File():
    """
    :param socket: 服务端套接字
    :param root: 主窗口
    :return:
    """
    socket_Server=socket_server()
    new_socket, addr = socket_Server.accept()
    #获取客户端发送的消息头
    msg_header=new_socket.recv(max_len)
    header=json.loads(msg_header.decode('utf-8'))
    #输出客户端发送的消息头信息
    print(header)
    #保存接收文件的地方
    curr_path=os.getcwd()
    filename=curr_path+'/server_recv_File/server_recv_'+header['filename']+header['msg_type']
    get_file_Size=header['msg_len']
    file_size=0
    #输出文件名和文件大小
    print('文件名: {}'.format(filename))
    print('file_size: {}'.format(get_file_Size))
    recv_count=0
    #如果文件不存在则创建
    if os.path.exists(filename)==False:
        with open(filename,'wb') as fp:
            while file_size!=get_file_Size:
                message=new_socket.recv(max_len)
                fp.write(message)
                file_size+=len(message)
                recv_count+=1
    else:
        with open(filename,'wb') as fp:
            while file_size!=get_file_Size:
                message=new_socket.recv(max_len)
                fp.write(message)
                file_size+=len(message)
                recv_count+=1
    print('接收次数: {}'.format(recv_count))
    new_socket.close()
    print('发送完成...')

#服务端接收客户端的下载文件请求,并进行发送
def server_Send_File():
    """
    :param new_socket:
    :return:
    """
    socket_Server = socket_server()
    new_socket, addr = socket_Server.accept()
    filepath=new_socket.recv(max_len).decode('utf-8')
    print('filepath: {}'.format(filepath))
    # 分离路径和文件名
    path, filename = os.path.split(filepath)
    print('path: {}'.format(path))
    print('filename: {}'.format(filename))
    # 分离文件名和文件后缀
    file, class_file = os.path.splitext(filename)
    # 首先将消息头发送至服务端
    # 获取文件大小
    # file_size=os.path.getsize(filename)
    file_Size = os.stat(filepath).st_size
    msg_header = {'filename': file, 'msg_type': class_file, 'msg_len': file_Size}
    msg_header_bytes = bytes(json.dumps(msg_header), encoding='utf-8')
    # 当消息头的长度不满1024时,使用空格填充
    msg_header_bytes += b'' * (max_len - len(msg_header_bytes))
    new_socket.send(msg_header_bytes)
    file_len = 0
    recv_count = 0
    # 发送的文件头大小
    print('msg_header_bytes: {}'.format(len(msg_header_bytes)))
    # 发送的文件大小
    print('file_size: {}'.format(file_Size))
    with open(filepath, 'rb') as fp:
        while file_len != file_Size:
            message = fp.read(max_len)
            new_socket.send(message)
            file_len += len(message)
            recv_count += 1
    print('发送次数: {}'.format(recv_count))

    new_socket.close()
    print('发送完成...')

if __name__=='__main__':
    print('Pycharm')
    Server_Recv_File()

客户端

clinet.py

import os
import tkinter

import cv2
import json
import socket
import threading
from tkinter import ttk
#读取文件的最大数
max_len=1024

def socket_client():
    #端口号和IP地址
    remote_PORT=5555
    remote_IP=socket.gethostbyname(socket.gethostname())
    remote_addr=(remote_IP,remote_PORT)

    #绑定端口号和IP地址
    socket_Client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    socket_Client.connect(remote_addr)
    return socket_Client

def ProgressBar(root,text):
    label=tkinter.Label(root,text=text,font=('黑体',14))
    label.place(x=100,y=500)
    progressbar=ttk.Progressbar(root)
    progressbar.place(x=200,y=500)
    #设置进度条的最大值
    progressbar['maximum']=100
    #设置进度条的长度
    progressbar['length']=280
    #初始化初值
    progressbar['value']=0

    return progressbar

def Client_Send_File(socket_Client,filepath,root):
    """
    :param socket: 客户端套接字
    :param filename: 要传输的文件
    :param root:主窗口
    :return:
    """
    progressbar=ProgressBar(root,'发送进度')
    #分离路径和文件名
    path, filename = os.path.split(filepath)
    print('path: {}'.format(path))
    print('filename: {}'.format(filename))
    #分离文件名和文件后缀
    file, class_file = os.path.splitext(filename)
    #首先将消息头发送至服务端
    #获取文件大小
    # file_size=os.path.getsize(filename)
    file_Size=os.stat(filepath).st_size
    msg_header={'filename':file,'msg_type':class_file,'msg_len':file_Size}
    msg_header_bytes=bytes(json.dumps(msg_header),encoding='utf-8')
    #当消息头的长度不满1024时,使用空格填充
    msg_header_bytes+=b''*(max_len-len(msg_header_bytes))
    socket_Client.send(msg_header_bytes)
    file_len=0
    recv_count=0
    #发送的文件头大小
    print('msg_header_bytes: {}'.format(len(msg_header_bytes)))
    #发送的文件大小
    print('file_size: {}'.format(file_Size))
    with open(filepath,'rb') as fp:
        while file_len!=file_Size:
            message=fp.read(max_len)
            socket_Client.send(message)
            file_len+=len(message)
            progressbar['value']=file_len/file_Size*100
            recv_count+=1
    print('发送次数: {}'.format(recv_count))

    socket_Client.close()
    print('发送完成...')

#客户端从服务端下载文件
def Download_Server(socket_Client,filepath,root):
    """
    :param socket_Client: 客户端套接字
    :param filepath: 文件路径
    :param root: 主窗口
    :return:
    """
    progressbar=ProgressBar(root,'下载进度')
    socket_Client.send(filepath.encode('utf-8'))
    # 获取客户端发送的消息头
    msg_header = socket_Client.recv(max_len)
    header = json.loads(msg_header.decode('utf-8'))
    # 输出客户端发送的消息头信息
    print(header)
    # 保存接收文件的地方
    curr_path = os.getcwd()
    filename = curr_path + '\\client_recv_File\\client_recv_' + header['filename'] + header['msg_type']
    get_file_Size = header['msg_len']
    file_size = 0
    # 输出文件名和文件大小
    print('文件名: {}'.format(filename))
    print('file_size: {}'.format(get_file_Size))
    recv_count = 0
    # 如果文件不存在则创建
    if os.path.exists(filename) == False:
        with open(filename, 'wb') as fp:
            while file_size != get_file_Size:
                message = socket_Client.recv(max_len)
                fp.write(message)
                file_size += len(message)
                progressbar['value']=file_size/get_file_Size*100
                recv_count += 1
    else:
        with open(filename, 'wb') as fp:
            while file_size != get_file_Size:
                message = socket_Client.recv(max_len)
                fp.write(message)
                file_size += len(message)
                progressbar['value'] = file_size / get_file_Size * 100
                recv_count += 1
    print('接收次数: {}'.format(recv_count))
    socket_Client.close()
    print('下载完成...')

if __name__=='__main__':
    print('Pycharm')
    socket_Client=socket_client()
    Client_Send_File(socket_Client,'File\\2014.rar')

总代码


import os,cv2,socket,tkinter,threading
import Client
import Server
from tkinter import ttk
from PIL import Image,ImageTk
from tkinter import filedialog
from tkinter.messagebox import showerror,showinfo,showwarning

root=tkinter.Tk()
#设置主窗口标题
root.title('远程更新——Keep_Trying_Go')
#设置主窗口大小
root['width']=900
root['height']=500
#固定窗口大小
root.resizable(0,0)
#设置主窗口背景颜色
root['background']='#FFFFFF'
#设置主窗口图标
#设置标题为图像形式,第一个参数设置为True,表示该图标适用于所有的窗口
#这里注意图像格式为.png,就算是从.jpg到.png的格式转换也不能,只能是.png格式
root.iconphoto(True,tkinter.PhotoImage(file='2.png'))

#背景图自适应大小
def ChangeBackground(w,h,w_box,h_box,PIL_Image):
    """
    :param w: 图片的宽度
    :param h: 图片的高度
    :param w_box: 画布的宽度
    :param h_box: 画布的高度
    :param PIL_Image:
    :return:
    """
    factor_w=1.0*w_box/w
    factor_h=1.0*h_box/h
    factor=min([factor_h,factor_w])
    #新的图片高度和宽度
    width=int(w*factor)
    height=int(h*factor)
    print('width: {}'.format(width))
    print('height: {}'.format(height))
    return PIL_Image.resize((width,height),Image.Resampling.LANCZOS)

tk_image_file=''
def setBackground(root,filename):
    """
    :param root: 主窗口
    :return:
    """
    global tk_image_file
    PIL_Image=Image.open(filename)
    w,h=PIL_Image.size
    PIL_Image_Size=ChangeBackground(w,h,600,450,PIL_Image)
    # PIL.ImageShow.show(PIL_Image_Size)
    try:
        #方式一
        #创建画布
        canvas=tkinter.Canvas(root,bg='white',width=598,height=450,borderwidth=1)
        canvas.place(x=5,y=0)
        #加在图片文件
        tk_image_file=ImageTk.PhotoImage(PIL_Image_Size)
        #将图片放置在创建的画布上
        image=canvas.create_image(0,0,anchor='nw',image=tk_image_file)
        # #将图像放置画布上端,也就是主窗口‘前方’
        # canvas.pack(side='top')
        #方法二
        # label=tkinter.Label(root,image=tk_image_file,width=600,height=450)
        # label.place(x=90,y=0)
    except :
        print('加载图像出错')

def SelectBackground(root):
    """
    :param root:
    :return:
    """
    filename=filedialog.askopenfilename(title='选择传输文件')
    if not filename:
        showinfo(title='提示',message='未选择传输文件')
        # 如果没有选择采用默认
        filename='2.png'
    setBackground(root,filename)
btn_cov=tkinter.Button(root,text='修改背景',font=('newspaper',14),width=17,height=1,cursor='hand2',command=lambda :SelectBackground(root),bg='#00FF7F')
btn_cov.place(x=615,y=300) # 350

def CloseEvent(root):
    """
    :param root:
    :return:
    """
    btn_close=tkinter.Button(root,text='退出',font=('newspaper',14),width=17,height=1,cursor='hand2',command=root.destroy,background='#708090')
    btn_close.place(x=615,y=400)

def SelectFile(root):
    """
    :param root:
    :return:
    """
    filename=filedialog.askopenfilename(title='选择传输文件')
    if not filename:
        showinfo(title='提示',message='请选择发送文件')
        # 如果没有选择采用默认
        filename='main.py'
    socket_Client=Client.socket_client()
    threading_client=threading.Thread(target=Client.Client_Send_File,args=(socket_Client,filename,root))
    threading_client.start()

btn_client=tkinter.Button(root,text='选择发送文件',font=('newspaper',14),width=17,height=1,cursor='hand2',bg='#00FF7F',command=lambda :SelectFile(root))
btn_client.place(x=615,y=90)

def SwitchServer(root):
    """
    :param root:
    :return:
    """
    threading_server=threading.Thread(target=Server.Server_Recv_File)
    threading_server.start()

btn_client=tkinter.Button(root,text='开启接收文件服务端',font=('newspaper',14),width=17,height=1,cursor='hand2',bg='#00FF7F',command=lambda :SwitchServer(root))
btn_client.place(x=615,y=200) # 140

def SelectdownloadFile(root):
    filename=filedialog.askopenfilename(title='选择下载文件')
    if not filename:
        showinfo(title='提示',message='请选择您要下载的文件')
        #如果没有选择采用默认
        filename='main.py'
    socket_Client=Client.socket_client()
    threading_client=threading.Thread(target=Client.Download_Server,args=(socket_Client,filename,root))
    threading_client.start()

# btn_client_down=tkinter.Button(root,text='选择下载文件',font=('newspaper',14),width=17,height=1,cursor='hand2',bg='#00FF7F',command=lambda :SelectdownloadFile(root))
# btn_client_down.place(x=615,y=210)

def SwitchdownloadServer(root):
    """
    :param root:
    :return:
    """
    threading_server=threading.Thread(target=Server.server_Send_File)
    threading_server.start()

# btn_server_send=tkinter.Button(root,text='开启下载文件服务端',font=('newspaper',14),width=17,height=1,cursor='hand2',bg='#00FF7F',command=lambda :SwitchdownloadServer(root))
# btn_server_send.place(x=615,y=260)

if __name__=='__main__':
    print('welcome ...')
    setBackground(root, filename='bj.png')
    CloseEvent(root)
    root.mainloop()
目录
相关文章
|
2月前
|
监控 Ubuntu Linux
视频监控笔记(五):Ubuntu和windows时区同步问题-your clock is behind
这篇文章介绍了如何在Ubuntu和Windows系统中通过设置相同的时区并使用ntp服务来解决时间同步问题。
84 4
视频监控笔记(五):Ubuntu和windows时区同步问题-your clock is behind
|
2月前
|
监控 前端开发 JavaScript
视频监控笔记(六): 如何快速通过Boostrap创建视频监控网页,保姆级别教程
本文是一篇保姆级教程,介绍了如何使用Bootstrap和Python的Flask框架快速创建视频监控网页。文章首先介绍了Bootstrap的基本概念,然后详细阐述了在PyCharm中创建项目、安装Flask和Bootstrap、编写Python代码设置路由、以及创建和定制HTML模板的步骤。最后,还提到了运行和测试网页的方法。
30 1
视频监控笔记(六): 如何快速通过Boostrap创建视频监控网页,保姆级别教程
|
2月前
|
JSON 数据格式 Python
Socket学习笔记(一):python通过socket实现客户端到服务器端的文件传输
本文介绍了如何使用Python的socket模块实现客户端到服务器端的文件传输,包括客户端发送文件信息和内容,服务器端接收并保存文件的完整过程。
184 1
Socket学习笔记(一):python通过socket实现客户端到服务器端的文件传输
|
2月前
|
缓存 监控 计算机视觉
视频监控笔记(三):opencv结合ffmpeg获取rtsp摄像头相关信息
本文介绍了如何使用OpenCV结合FFmpeg获取RTSP摄像头信息,包括网络架构、视频监控系统组成、以及如何读取和显示网络摄像头视频流。
76 1
|
6月前
|
存储 缓存 网络协议
技术笔记:socket网络实现
技术笔记:socket网络实现
26 0
|
前端开发
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之socket发送文本状态2
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之socket发送文本状态2
61 0
|
前端开发
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之自定义指令创建之2
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之自定义指令创建之2
55 0
|
JavaScript 前端开发
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之原生dom导入和移除的技巧2
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之原生dom导入和移除的技巧2
43 0
|
前端开发
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之响应式和视图数据渲染1
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之响应式和视图数据渲染1
66 1
|
前端开发
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之创建客户端和socket链接1
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之创建客户端和socket链接1
62 0