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()
    
  • 相关阅读:
    集合Hashtable Dictionary Hashset
    ArrayList 排序Sort()方法扩展
    Visual Studio 2019使用Intel C++ Compiler
    Visual Studio工具 vcpkg简介
    PE结构学习
    netapi32的一些利用方式
    windows api和创建服务
    导出firfox保存的密码
    在Active Directory中滥用无约束Kerberos委派
    Service Principal Name (SPN)
  • 原文地址:https://www.cnblogs.com/songhaixing/p/14299682.html
Copyright © 2011-2022 走看看