上传下载程序,支持动态更换IP和端口, 上传下载, 进度条显示, 正则校验文件格式, hash校验文件完整性

本文主要是介绍上传下载程序,支持动态更换IP和端口, 上传下载, 进度条显示, 正则校验文件格式, hash校验文件完整性,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

支持动态更换IP和端口, 上传下载, 进度条显示, 正则校验文件格式, hash校验文件完整性

另有已封装好的exe文件

客户端

# coding=utf-8
from socket import *
import json
import struct
import os,re
import hashlibip = 0
port = 0# 打印进度条
def progress(percent, symbol='█', width=40):if percent > 1:  # 超过 100% 的时候让其停在 1percent = 1  # 可以避免进度条溢出show_progress = ("▌%%-%ds▌" % width) % (int(percent * width) * symbol)print("\r%s %.2f%%" % (show_progress, percent * 100), end='')# hash 校验
def Hash_md5(file_path:str):m = hashlib.md5()m.update(str(os.path.getsize(file_path)).encode("utf-8"))return m.hexdigest()# 连接
def connection():client = socket(AF_INET,SOCK_STREAM)client.connect((ip,port))return client# 下载
def download(client):client.send("1".encode("utf-8"))while 1:try:file_path = input("Please enter the file path(q/exit)>>").strip()if file_path.lower() == "q":breakif len(file_path) == 0:continueto_path = input("Please enter the save directory(q/back)>>").strip()if to_path.lower() == "q":continueif not os.path.isdir(to_path):print("not find");continueelse:file_name = input("Please enter filename(q/back)>>").strip()if file_name.lower() == "q":continueif re.search(r'[/|:*"<>\\]',file_name):print(r'Filenames cannot have these symbols:/|:*"<>\\');continuegoal_path = os.path.join(to_path,file_name)client.send(file_path.encode("utf-8"))bytes_4 = client.recv(4)if bytes_4.decode("utf-8") == "4044":print("not find");continueelse:header_bytes_len = struct.unpack("i",bytes_4)[0]header_bytes = client.recv(header_bytes_len)header_dic = json.loads(header_bytes.decode("utf-8"))date_len = header_dic["file_size"]hash_md5 = header_dic["hash"]recv_len = 0with open(goal_path,"wb")as f:while 1:date = client.recv(1024)recv_len += len(date)percent = recv_len / date_len  # 接收的比例progress(percent, width=40)    # 进度条的宽度40f.write(date)if recv_len == date_len: breakif hash_md5 == Hash_md5(goal_path):          # hash 值校验print("\nHash auth succeed\nFile saved...")continueelse:os.remove(goal_path)               # 校验失败内容删除print("Hash auth failed!!")except Exception as E:print(E);break# 上传
def uploading(client):client.send("2".encode("utf-8"))while 1:try:file_path = input("Please enter the path of the uploaded file(q/exit)>>").strip()if file_path.lower() == "q":breakfile_path = os.path.normpath(file_path)if not os.path.isfile(file_path):print("not find");continuegoal_path = input("Please enter the destination path(q/back)>>").strip()if goal_path.lower() == "q":continuegoal_path = os.path.normpath(goal_path)client.send(goal_path.encode("utf-8"))bytes_4 = client.recv(4)if bytes_4.decode("utf-8") == "4044":print("not find");continueelse:file_name = input("Please name the new file(q/back)>>").strip()if file_name.lower() == "q":continueif re.search(r'[/|:*"<>\\]',file_name):print(r'Filenames cannot have these symbols:/|:*"<>\\');continuegoal_file_path = os.path.join(goal_path,file_name)file_size = os.path.getsize(file_path)file_name = os.path.basename(file_path)md5 = Hash_md5(file_path)header_dic = {"file_name": file_name, "file_size": file_size, "hash": md5,"file_path":goal_file_path}header_json = json.dumps(header_dic)header_bytes = header_json.encode("utf-8")header_bytes_len = struct.pack("i", len(header_bytes))client.send(header_bytes_len)client.send(header_bytes)send_len = 0with open(file_path, "rb")as f:for line in f:send_len += len(line)percent = send_len / file_size # 接收的比例progress(percent, width=40)    # 进度条的宽度40client.send(line)print("\nsuccessfully upload!")except Exception as E:print(E);breakfunc_dic = {"1":["download ",download],"2":["upload",uploading],"3":["IP Settings",download],
}# 连接服务端ip和端口并选择功能
def run():while True:print("Please enter the correct IP and port")global ip,portip = input("Please enter IP(q/exit)>>").strip()if ip.lower() == "q":breakport = input("Please enter PORT(q/exit)>>").strip()if port.lower() == "q":breakif port.isdigit():port = int(port)else:print("Please enter the number")continuetry:client = connection()  # 检测连接是否建立成功except Exception as E:print(E);continuewhile 1:for k,v in func_dic.items():print(f"{k} : {v[0]}")select = input("Please select function>>")if select == "3":breakif select in func_dic:func_dic[select][1](client)run()

服务端

# coding=utf-8
from socket import *
import json
import struct
import os,hashlib# 绑定服务端地址
def connection():server = socket(AF_INET,SOCK_STREAM)server.bind((ip,port))server.listen(5)return server# 建立连接选择功能
def recv_send(server):while 1:print("connection...")conn,addr = server.accept()print(f"from {addr} conn")select = conn.recv(1)if select.decode("utf-8") == "1":download(conn)elif select.decode("utf-8") == "2":uploading(conn)# 客户端下载
def download(conn):while 1:try:file_path = conn.recv(1024)file_path = os.path.normpath(file_path.decode("utf-8"))if not os.path.isfile(file_path):conn.send("4044".encode("utf-8"))else:file_size = os.path.getsize(file_path)file_name = os.path.basename(file_path)m = hashlib.md5()m.update(str(file_size).encode("utf-8"))md5 = m.hexdigest()header_dic = {"file_name":file_name,"file_size":file_size,"hash":md5}header_json = json.dumps(header_dic)header_bytes = header_json.encode("utf-8")header_bytes_len = struct.pack("i",len(header_bytes))conn.send(header_bytes_len)conn.send(header_bytes)with open(file_path,"rb")as f:for line in f:conn.send(line)except Exception:break# 客户端的上传
def uploading(conn):while 1:try:dir_path = conn.recv(1024)dir_path = os.path.normpath(dir_path.decode("utf-8"))if not os.path.isdir(dir_path):conn.send("4044".encode("utf-8"));continueelse:conn.send("4444".encode("utf-8"))bytes_4 = conn.recv(4)header_bytes_len = struct.unpack("i", bytes_4)[0]header_bytes = conn.recv(header_bytes_len)header_dic = json.loads(header_bytes.decode("utf-8"))date_len = header_dic["file_size"]goal_file_path = header_dic["file_path"]recv_len = 0with open(goal_file_path, "wb")as f:while 1:date = conn.recv(1024)recv_len += len(date)f.write(date)if recv_len == date_len: breakcontinueexcept Exception as E:print(E);breakdef run():while True:print("Please enter the correct IP and port")global ip, portip = input("Please enter IP(q/exit)>>").strip()if ip.lower() == "q": breakport = input("Please enter PORT(q/exit)>>").strip()if port.lower() == "q": breakif port.isdigit():port = int(port)try:server = connection()except Exception as E:print(E);continuerecv_send(server)else:print("Please enter the number")continuerun()

这篇关于上传下载程序,支持动态更换IP和端口, 上传下载, 进度条显示, 正则校验文件格式, hash校验文件完整性的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/628077

相关文章

Spring Boot 实现 IP 限流的原理、实践与利弊解析

《SpringBoot实现IP限流的原理、实践与利弊解析》在SpringBoot中实现IP限流是一种简单而有效的方式来保障系统的稳定性和可用性,本文给大家介绍SpringBoot实现IP限... 目录一、引言二、IP 限流原理2.1 令牌桶算法2.2 漏桶算法三、使用场景3.1 防止恶意攻击3.2 控制资源

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五

SpringBoot服务获取Pod当前IP的两种方案

《SpringBoot服务获取Pod当前IP的两种方案》在Kubernetes集群中,SpringBoot服务获取Pod当前IP的方案主要有两种,通过环境变量注入或通过Java代码动态获取网络接口IP... 目录方案一:通过 Kubernetes Downward API 注入环境变量原理步骤方案二:通过

华为鸿蒙HarmonyOS 5.1官宣7月开启升级! 首批支持名单公布

《华为鸿蒙HarmonyOS5.1官宣7月开启升级!首批支持名单公布》在刚刚结束的华为Pura80系列及全场景新品发布会上,除了众多新品的发布,还有一个消息也点燃了所有鸿蒙用户的期待,那就是Ha... 在今日的华为 Pura 80 系列及全场景新品发布会上,华为宣布鸿蒙 HarmonyOS 5.1 将于 7

C#实现将Office文档(Word/Excel/PDF/PPT)转为Markdown格式

《C#实现将Office文档(Word/Excel/PDF/PPT)转为Markdown格式》Markdown凭借简洁的语法、优良的可读性,以及对版本控制系统的高度兼容性,逐渐成为最受欢迎的文档格式... 目录为什么要将文档转换为 Markdown 格式使用工具将 Word 文档转换为 Markdown(.

Golang 日志处理和正则处理的操作方法

《Golang日志处理和正则处理的操作方法》:本文主要介绍Golang日志处理和正则处理的操作方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录1、logx日志处理1.1、logx简介1.2、日志初始化与配置1.3、常用方法1.4、配合defer

Linux中修改Apache HTTP Server(httpd)默认端口的完整指南

《Linux中修改ApacheHTTPServer(httpd)默认端口的完整指南》ApacheHTTPServer(简称httpd)是Linux系统中最常用的Web服务器之一,本文将详细介绍如何... 目录一、修改 httpd 默认端口的步骤1. 查找 httpd 配置文件路径2. 编辑配置文件3. 保存

python编写朋克风格的天气查询程序

《python编写朋克风格的天气查询程序》这篇文章主要为大家详细介绍了一个基于Python的桌面应用程序,使用了tkinter库来创建图形用户界面并通过requests库调用Open-MeteoAPI... 目录工具介绍工具使用说明python脚本内容如何运行脚本工具介绍这个天气查询工具是一个基于 Pyt

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

Ubuntu设置程序开机自启动的操作步骤

《Ubuntu设置程序开机自启动的操作步骤》在部署程序到边缘端时,我们总希望可以通电即启动我们写好的程序,本篇博客用以记录如何在ubuntu开机执行某条命令或者某个可执行程序,需要的朋友可以参考下... 目录1、概述2、图形界面设置3、设置为Systemd服务1、概述测试环境:Ubuntu22.04 带图