zoukankan      html  css  js  c++  java
  • 🍖ftp上传下载

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

    另有已封装好的exe文件

    客户端

    # coding=utf-8
    from socket import *
    import json
    import struct
    import os,re
    import hashlib
    
    ip = 0
    port = 0
    
    # 打印进度条
    def progress(percent, symbol='█', width=40):
        if percent > 1:  # 超过 100% 的时候让其停在 1
            percent = 1  # 可以避免进度条溢出
        show_progress = ("▌%%-%ds▌" % width) % (int(percent * width) * symbol)
        print("
    %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":break
                if len(file_path) == 0:continue
                to_path = input("Please enter the save directory(q/back)>>").strip()
                if to_path.lower() == "q":continue
                if not os.path.isdir(to_path):
                    print("not find");continue
                else:
                    file_name = input("Please enter filename(q/back)>>").strip()
                    if file_name.lower() == "q":continue
                    if re.search(r'[/|:*"<>\]',file_name):
                        print(r'Filenames cannot have these symbols:/|:*"<>\');continue
                    goal_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");continue
                else:
                    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 = 0
                    with 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)    # 进度条的宽度40
                            f.write(date)
                            if recv_len == date_len: break
    
                    if hash_md5 == Hash_md5(goal_path):          # hash 值校验
                        print("
    Hash auth succeed
    File saved...")
                        continue
                    else:
                        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":break
                file_path = os.path.normpath(file_path)
                if not os.path.isfile(file_path):
                    print("not find");continue
                goal_path = input("Please enter the destination path(q/back)>>").strip()
                if goal_path.lower() == "q":continue
                goal_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");continue
                else:
                    file_name = input("Please name the new file(q/back)>>").strip()
                    if file_name.lower() == "q":continue
                    if re.search(r'[/|:*"<>\]',file_name):
                        print(r'Filenames cannot have these symbols:/|:*"<>\');continue
                    goal_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 = 0
                    with open(file_path, "rb")as f:
                        for line in f:
                            send_len += len(line)
                            percent = send_len / file_size # 接收的比例
                            progress(percent, width=40)    # 进度条的宽度40
                            client.send(line)
                        print("
    successfully upload!")
            except Exception as E:
                print(E);break
    
    func_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,port
            ip = input("Please enter IP(q/exit)>>").strip()
            if ip.lower() == "q":break
            port = input("Please enter PORT(q/exit)>>").strip()
            if port.lower() == "q":break
            if port.isdigit():
                port = int(port)
            else:
                print("Please enter the number")
                continue
            try:
                client = connection()  # 检测连接是否建立成功
            except Exception as E:
                print(E);continue
            while 1:
                for k,v in func_dic.items():
                    print(f"{k} : {v[0]}")
                select = input("Please select function>>")
                if select == "3":break
                if 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"));continue
                else:
                    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 = 0
                    with 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: break
                    continue
            except Exception as E:
                print(E);break
    
    def run():
        while True:
            print("Please enter the correct IP and port")
            global ip, port
            ip = input("Please enter IP(q/exit)>>").strip()
            if ip.lower() == "q": break
            port = input("Please enter PORT(q/exit)>>").strip()
            if port.lower() == "q": break
            if port.isdigit():
                port = int(port)
                try:
                    server = connection()
                except Exception as E:
                    print(E);continue
                recv_send(server)
            else:
                print("Please enter the number")
                continue
    
    run()
    
  • 相关阅读:
    Get-CrmSetting返回Unable to connect to the remote server的解决办法
    Dynamics 365中的常用Associate和Disassociate消息汇总
    Dynamics 365 Customer Engagement V9 活动源功能报错的解决方法
    Dynamics Customer Engagement V9版本配置面向Internet的部署时候下一步按钮不可点击的解决办法
    Dynamics 365检查工作流、SDK插件步骤是否选中运行成功后自动删除系统作业记录
    注意,更改团队所属业务部门用Update消息无效!
    Dynamics 365的审核日志分区删除超时报错怎么办?
    Dynamics 365使用Execute Multiple Request删除系统作业实体记录
    Dynamics 365的系统作业实体记录增长太快怎么回事?
    Dynamics CRM日期字段查询使用时分秒的方法
  • 原文地址:https://www.cnblogs.com/songhaixing/p/14299682.html
Copyright © 2011-2022 走看看