zoukankan      html  css  js  c++  java
  • python_网络编程之端点续传

    这个例子分为服务端和客户端,都做了大量的注释,很容易读懂

    服务端

    ##以下代码是梳理思路
    # import socketserver
    # import os  #使用os模块的join方法
    # import json
    # cod={'1001':'开始上传','1002':'开始续传'}
    # class Nbserver(socketserver.BaseRequestHandler):
    #     def handle(self):
    #         while 1:
    #             # 1 , 接受命令
    #             upload_cmd_bytes=self.request.recv(2048) #最大是8k
    #             # upload_cmd_str=json.loads(upload_cmd_bytes).decode("utf8")  #错误的写法
    #             cmd_dic = json.loads(upload_cmd_bytes.decode("utf8"))  #是字节有解码的方法
    #
    #
    #             # 2,获取文件信息
    #             file_md5=cmd_dic['md5']
    #             home=r'E:老男孩课程mysql_db'
    #             file_mdf_path=os.path.join(home,'zhangzijie',file_md5)
    #
    #             exist=os.path.exists(file_mdf_path)
    #             if not exist: #不续传
    #                 #我没有这个文件,你开始给我传
    #                 #设计状态码
    #                 response = {'code': 1001}
    #                 self.request.sendall(b'1001')
    #             else:
    #                 #怎么续传呢?你的告诉客户端我已经有多少了,你已经给我传了多少了,对方才能
    #                 #从断开的那里进行继续传
    #                 #根据文件路径获取大小
    #                 exist_szie=os.stat(file_mdf_path).st_size
    #                 #定义一个协议
    #                 response={'code':1002,'size':exist_szie}
    #                 self.request.sendall(json.dumps(response).encode("utf-8"))
    #                 self.request.sendall(b'1002')
    #
    #
    #             # print(cmd_dic)
    #
    #
    # server=socketserver.ThreadingTCPServer(('127.0.0.1',8001),Nbserver)
    # server.serve_forever()
    
    ###########################################################################################
    # 下面这个例子可以运行,就是上传的目录64行的zhangzijie需要指定
    # 开始编写上传部分
    # import socketserver
    # import os  #使用os模块的join方法
    # import json
    # cod={'1001':'开始上传','1002':'开始续传'}
    # class Nbserver(socketserver.BaseRequestHandler):
    #     def handle(self):
    #         while 1:
    #             # 1 , 接受命令
    #             upload_cmd_bytes=self.request.recv(2048) #最大是8k
    #             # upload_cmd_str=json.loads(upload_cmd_bytes).decode("utf8")  #错误的写法
    #             cmd_dic = json.loads(upload_cmd_bytes.decode("utf8"))  #是字节有解码的方法《########
    #                                                                                               #
    #                                                                                               #
    #             # 2,获取文件信息                                                                   #
    #             file_md5=cmd_dic['md5']  #
    #             file_name=cmd_dic['file_name']
    #             home=r'E:老男孩课程day31ftp_projrct'                                                     #
    #             file_md5_path=os.path.join(home,'zhangzijie',file_md5)  #
    #             file_name_path = os.path.join(home, 'zhangzijie', file_name)
    #             upload_file_size=cmd_dic['size']           #所有文件信息都在上面取到的字典里《########
    #             exist=os.path.exists(file_md5_path)
    #             if not exist: #不续传
    #                 #我没有这个文件,你开始给我传
    #                 #设计状态码
    #                 response = {'code': 1001}
    #                 self.request.sendall(json.dumps(response).encode("utf8"))
    #                 f=open(file_md5_path,mode='wb')
    #
    #                 recv_size=0
    #                 #接受上传的文件内容
    #                 while recv_size<upload_file_size:
    #                     data=self.request.recv(1024)
    #                     f.write(data)   #写过来的东西都在内存中
    #                     f.flush()       #把内存中的东西刷到硬盘中
    #                     recv_size+=len(data)
    #                 f.close()
    #
    #                 #改名字,
    #                 #os模块的额rename在windows系统中的python2中会报错
    #                 #os.rename(file_md5_path,file_name_path)
    #                 #shutil模块在哪都不会报错,除了改文件名还可以该文件夹的名字
    #                 import shutil
    #                 shutil.move(file_md5_path,file_name_path)
    #
    #             else:
    #                 #怎么续传呢?你的告诉客户端我已经有多少了,你已经给我传了多少了,对方才能
    #                 #从断开的那里进行继续传
    #                 #根据文件路径获取大小
    #                 exist_szie=os.stat(file_md5_path).st_size
    #                 #定义一个协议
    #                 response={'code':1002,'size':exist_szie}
    #                 self.request.sendall(json.dumps(response).encode("utf-8"))
    #                 self.request.sendall(b'1002')
    #
    #                 f = open(file_md5_path, mode='ab')  #这里是追加
    #
    #                 # recv_size = 0     #这里的总大小就不在是0了,而是已经接受了的大小
    #                 recv_size=exist_szie         #这里有个方法,对于后面的变量名,类似的用到了前面的名字
    #                                              #可以不用重新再起名字,直接重新赋值把前面的覆盖掉就可以了
    #                 # 接受上传的文件内容
    #                 while recv_size < upload_file_size:
    #                     data = self.request.recv(1024)
    #                     f.write(data)  # 写过来的东西都在内存中
    #                     f.flush()  # 把内存中的东西刷到硬盘中
    #                     recv_size += len(data)
    #                 f.close()
    #
    #
    #             # print(cmd_dic)
    #
    #
    # server=socketserver.ThreadingTCPServer(('127.0.0.1',8001),Nbserver)
    # server.serve_forever()
    # #####################################################################################
    # 下面这个例子对方法进行归类
    # 开始编写上传部分
    import socketserver
    import os  #使用os模块的join方法
    import json
    cod={'1001':'开始上传','1002':'开始续传'}
    
    def upload(cmd_dic,conn):  #用conn代替了下面类中的self.request
        file_md5 = cmd_dic['md5']  #
        file_name = cmd_dic['file_name']
        home = r'E:老男孩课程day31ftp_projrct'  #
        file_md5_path = os.path.join(home, 'zhangzijie', file_md5)  #
        file_name_path = os.path.join(home, 'zhangzijie', file_name)
        upload_file_size = cmd_dic['size']  # 所有文件信息都在上面取到的字典里《########
        exist = os.path.exists(file_md5_path)
        if not exist:  # 不续传
            # 我没有这个文件,你开始给我传
            # 设计状态码
            response = {'code': 1001}
            conn.sendall(json.dumps(response).encode("utf8"))
            f = open(file_md5_path, mode='wb')
    
            recv_size = 0
            # 接受上传的文件内容
            while recv_size < upload_file_size:
                data = conn.recv(1024)
                f.write(data)  # 写过来的东西都在内存中
                f.flush()  # 把内存中的东西刷到硬盘中
                recv_size += len(data)
            f.close()
    
            # 改名字,
            # os模块的额rename在windows系统中的python2中会报错
            # os.rename(file_md5_path,file_name_path)
            # shutil模块在哪都不会报错,除了改文件名还可以该文件夹的名字
            import shutil
            shutil.move(file_md5_path, file_name_path)
    
        else:
            # 怎么续传呢?你的告诉客户端我已经有多少了,你已经给我传了多少了,对方才能
            # 从断开的那里进行继续传
            # 根据文件路径获取大小
            exist_szie = os.stat(file_md5_path).st_size
            # 定义一个协议
            response = {'code': 1002, 'size': exist_szie}
            conn.sendall(json.dumps(response).encode("utf-8"))
            conn.sendall(b'1002')
    
            f = open(file_md5_path, mode='ab')  # 这里是追加
    
            # recv_size = 0     #这里的总大小就不在是0了,而是已经接受了的大小
            recv_size = exist_szie  # 这里有个方法,对于后面的变量名,类似的用到了前面的名字
            # 可以不用重新再起名字,直接重新赋值把前面的覆盖掉就可以了
            # 接受上传的文件内容
            while recv_size < upload_file_size:
                data = conn.recv(1024)
                f.write(data)  # 写过来的东西都在内存中
                f.flush()  # 把内存中的东西刷到硬盘中
                recv_size += len(data)
            f.close()
    
    
    class Nbserver(socketserver.BaseRequestHandler):
        def handle(self):
            while 1:
                # 1 , 接受命令
                upload_cmd_bytes=self.request.recv(2048) #最大是8k
                # upload_cmd_str=json.loads(upload_cmd_bytes).decode("utf8")  #错误的写法
                cmd_dic = json.loads(upload_cmd_bytes.decode("utf8"))  #是字节有解码的方法《########
    
                if cmd_dic['cmd']=='upload':
                    upload(cmd_dic,self.request) #函数调用的时候,实参传self.request
                elif cmd_dic['cmd']=='download':
                    pass       #下载的代码
                
    
    
    server=socketserver.ThreadingTCPServer(('127.0.0.1',8001),Nbserver)
    server.serve_forever()
    ftp断点续传服务端

    客户端

    ##以下代码是梳理思路
    # import socket
    # import json
    # import hashlib
    # import os
    #
    # def file_md5(file_path):
    #     """
    #     对文件进行md5加密
    #     :param file_path:
    #     :return:
    #     """
    #     obj=open(file_path,mode='rb')
    #     m=hashlib.md5()       #实例化MD5
    #     for line in obj:
    #         m.update(line)    #使用md5的update方法
    #     obj.close()
    #     return m.hexdidest()
    #
    # sk=socket.socket()
    # sk.connect(('127.0.0.1',8001))
    # while 1:
    #     cmd=input("请输入命令:")
    #     """
    #     1,自定义协议
    #     {'cmd':'upload','file_path':'.....'}
    #     """
    #     #获取文件的相关信息
    #     file_path="/.../"
    #     file_md5_val=file_md5(file_path)
    #     file_name= os.path.basename(file_path)
    #     file_size=os.stat(file_path).st_size
    #     cmd_dict={'cmd':'upload','file_name':file_name,'size':file_size}
    #
    #     suload_cmd_bytes=json.dumps(cmd_dict).encode("utf8")
    #     sk.sendall(suload_cmd_bytes)  # 推荐使用sendall
    #
    #     #等待服务端的响应
    #     response=json.loads(sk.recv(8096).decode("utf-8")) #通过序列化与反序列化,最后又转化成字典的操作
    #                                                        #这种最后就非常方便
    #     if response['code']==1001:
    #         #从头开始传
    #         pass
    #     else:
    #         #从断点开始续传
    #         exist_zise=response['size']
    
    ###########################################################################################
    # 下面的例子可以运行,就是上传的文件需要指定
    # 开始编写上传部分
    # import socket
    # import json
    # import hashlib
    # import os
    #
    # def file_md5(file_path):
    #     """
    #     对文件进行md5加密
    #     :param file_path:
    #     :return:
    #     """
    #     obj=open(file_path,mode='rb')
    #     m=hashlib.md5()       #实例化MD5
    #     for line in obj:
    #         m.update(line)    #使用md5的update方法
    #     obj.close()
    #     return m.hexdigest()
    #
    # sk=socket.socket()
    # sk.connect(('127.0.0.1',8001))
    # while 1:
    #     cmd=input("请输入命令:")
    #     """
    #     1,自定义协议
    #     {'cmd':'upload','file_path':file_path}
    #     """
    #     #获取文件的相关信息
    #     file_path="hello.py"
    #     file_md5_val=file_md5(file_path)
    #     file_name= os.path.basename(file_path)
    #     file_size=os.stat(file_path).st_size
    #     cmd_dict={'cmd':'upload','file_name':file_name,'size':file_size,'md5':file_md5_val}
    #
    #     suload_cmd_bytes=json.dumps(cmd_dict).encode("utf8")
    #     sk.sendall(suload_cmd_bytes)  # 推荐使用sendall
    #
    #     #等待服务端的响应
    #     response=json.loads(sk.recv(8096).decode("utf8")) #通过序列化与反序列化,最后又转化成字典的操作
    #                                                        #这种最后就非常方便
    #     if response['code']==1001:
    #         #从头开始上传,文件迭代,一行一行发
    #         # with  open(file_path,mode='rb') as f:
    #         #     for line in f:
    #         #         sk.sendall(line)
    #         #发送可以有两种方式,另外一种如下:
    #         f=open(file_path,mode="rb")
    #         send_size=0
    #         while send_size< file_size: #不能等于,如果是等于,就会一直循环
    #             data=f.read(1024)
    #             sk.sendall(data)
    #             send_size+=len(data)
    #         f.close()
    #
    #
    #     else:
    #         #从断点开始续传
    #         exist_zise=response['size']
    #         f=open(file_path,'rb')
    #         f.seek(exist_zise) #seek跳到某个字节
    #         send_size=exist_zise  #已经发送的等于断点处的字节大小
    #         while send_size< file_size:  #已发的字节小于总大小
    #             data=f.read(1024)
    #             sk.sendall(data)
    #             send_size+=len(data)
    #         f.close()
    
    
    # #####################################################################################
    
    # 下面的例子对方法进行归类
    # 开始编写上传部分
    import socket
    import json
    import hashlib
    import os
    import time
    #先对函数进行归类
    
    
    
    def file_md5(file_path):
        """
        对文件进行md5加密
        :param file_path:
        :return:
        """
        obj=open(file_path,mode='rb')
        m=hashlib.md5()       #实例化MD5
        for line in obj:
            m.update(line)    #使用md5的update方法
        obj.close()
        return m.hexdigest()
    
    #进度条
    def jdt(size,total_size):
        val = int(size/total_size * 100)
        time.sleep(0.1)
        print('
    %s%%|%s' %(val,"#"*val,), end='')
    
    
    def send_file(exist_zise,file_tocal_size):
        f = open(file_path, 'rb')
        f.seek(exist_zise)  # seek跳到某个字节
        send_size = exist_zise  # 已经发送的等于断点处的字节大小
        while send_size < file_tocal_size:  # 已发的字节小于总大小
            data = f.read(1024)
            sk.sendall(data)
            send_size += len(data)
            jdt(send_size,file_tocal_size)            #调用进度条函数
        f.close()
    
    def upload(file_path):
        #获取文件的相关信息
        file_md5_val=file_md5(file_path)
        file_name= os.path.basename(file_path)
        file_size=os.stat(file_path).st_size
        cmd_dict={'cmd':'upload','file_name':file_name,'size':file_size,'md5':file_md5_val}
    
        suload_cmd_bytes=json.dumps(cmd_dict).encode("utf8")
        sk.sendall(suload_cmd_bytes)  # 推荐使用sendall
    
        #等待服务端的响应
        response=json.loads(sk.recv(8096).decode("utf8")) #通过序列化与反序列化,最后又转化成字典的操作
                                                           #这种最后就非常方便
        if response['code']==1001:
            #从头开始上传,文件迭代,一行一行发
            # with  open(file_path,mode='rb') as f:
            #     for line in f:
            #         sk.sendall(line)
            #发送可以有两种方式,另外一种如下:
            f=open(file_path,mode="rb")
            send_file(0,file_size)
    
        else:
            #从断点开始续传
            exist_zise=response['size']
            send_file(exist_zise,file_size)
    
    
    
    
    sk=socket.socket()
    sk.connect(('127.0.0.1',8001))
    while 1:
        user_onput=input("请输入命令:")
        cmd,file_path=user_onput.split('|',maxsplit=1)
        if cmd=='upload':
            upload(file_path)
        elif cmd=='download':
            pass           #如果elif特别多可以考虑使用反射
    ftp断点续传客户端
  • 相关阅读:
    在Ubuntu中通过update-alternatives切换软件版本
    SCons: 替代 make 和 makefile 及 javac 的极好用的c、c++、java 构建工具
    mongodb 的使用
    利用grub从ubuntu找回windows启动项
    How to Repair GRUB2 When Ubuntu Won’t Boot
    Redis vs Mongo vs mysql
    java script 的工具
    python 的弹框
    how to use greendao in android studio
    python yield的终极解释
  • 原文地址:https://www.cnblogs.com/zhuhaofeng/p/9590954.html
Copyright © 2011-2022 走看看