zoukankan      html  css  js  c++  java
  • FTP作业代码

    服务端

    import socket,os,sys,json,struct,socketserver
    
    BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    SHARE_DIR=os.path.join(BASE_DIR,"share")
    TMP_DIR=os.path.join(BASE_DIR,"tmp")
    sys.path.append(BASE_DIR)
    from lib.md5sum import md5sum
    from lib.random_str import make_code
    
    class MyTcphandler(socketserver.BaseRequestHandler):
        def handle(self):
            conn = self.request
            print(conn)
            while True: #通信循环
                try:
                    data=conn.recv(1024)
                    if not data: break
                    params = json.loads(data.decode('utf-8'))  # params=['get','a.txt']
                    cmd = params[0]  #
                    if hasattr(self, cmd) and len(params)>=2:
                        func = getattr(self, cmd)
                        func(params)
                    else:
                        conn.send("N".encode("utf-8"))
                        print('33[45mcmd not exists33[0m')
                except Exception:
                    break
        def get(self,params): #params=['get','a.txt']
            filename=params[1] #filename='a.txt'
            filepath=os.path.join(SHARE_DIR,filename) #
            conn = self.request
            if os.path.exists(filepath):
                conn.send("Y".encode("utf-8"))
    
                #1、制作报头
                headers = {
                    'filename': filename,
                    "former_name":None,
                    'md5': md5sum(filepath),
                    'filesize': os.path.getsize(filepath),
                    'alias':make_code(16)
                }
                tmpfile=os.path.join(TMP_DIR,md5sum(filepath))
                if os.path.exists(tmpfile):
                    former_header=json.load(open(tmpfile,"r",encoding="utf-8"))
                    headers["former_name"]=former_header["alias"]
                headers_json = json.dumps(headers)
                headers_bytes = headers_json.encode('utf-8')
    
                # 2、先发报头的长度
                conn.send(struct.pack('i', len(headers_bytes)))
    
                # 3、发送报头
                conn.send(headers_bytes)
    
                signal=conn.recv(3).decode('utf-8')
    
                if signal=="old":
                    n_size = struct.unpack('i', conn.recv(4))[0]
                    n_bytes = conn.recv(n_size)
                    n_json = n_bytes.decode('utf-8')
                    n=json.loads(n_json)
                    with open(filepath,'rb') as f:
                        f.seek(n)
                        for line in f:
                            conn.send(line)
                elif signal=="new":
                    json.dump(headers,open(os.path.join(TMP_DIR,headers["md5"]),"w",encoding="utf-8"))
                    #4、发送真实的数据
                    with open(filepath,'rb') as f:
                        for line in f:
                            conn.send(line)
            else:
                conn.send("N".encode("utf-8"))
    
        def put(self):
            pass
    if __name__ == '__main__':
        #取代链接循环
        server=socketserver.ThreadingTCPServer(('127.0.0.1',8081),MyTcphandler)
        print('server starting...')
        server.serve_forever()

    客户端

    import socket,struct,json,os,sys
    
    BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    DOWNLOAD_DIR=os.path.join(BASE_DIR,"download")
    sys.path.append(BASE_DIR)
    from lib.md5sum import md5sum
    class FtpClient:
        def __init__(self,host,port):
            self.host=host
            self.port=port
            self.client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            self.client.connect((self.host,self.port))
    
        def interactive(self):
            while True:
                data=input('>>: ').strip() #get a.txt
                if not data:continue
                params=data.split() #parmas=['get','a.txt']
                cmd=params[0] #cmd='get'
                if hasattr(self,cmd):
                    func=getattr(self,cmd)
                    func(params) #func(['get','a.txt'])
    
        def get(self,params):
            params_json=json.dumps(params)
            self.client.send(params_json.encode('utf-8'))
            status=self.client.recv(1).decode('utf-8')
            if status == "Y":
                # 1、先接收报头的长度
                headers_size = struct.unpack('i', self.client.recv(4))[0]
                # 2、再收报头
                headers_bytes = self.client.recv(headers_size)
                headers_json = headers_bytes.decode('utf-8')
                headers_dic = json.loads(headers_json)
                print('========>', headers_dic)
                filename = headers_dic['filename']
                filesize = headers_dic['filesize']
                alias= headers_dic['alias']
                server_md5=headers_dic['md5']
                former_name= headers_dic["former_name"]
                aliaspath=os.path.join(DOWNLOAD_DIR, alias)
                filepath = os.path.join(DOWNLOAD_DIR, filename)
                if former_name:former_path=os.path.join(DOWNLOAD_DIR, former_name)
                if former_name and os.path.exists(former_path):
                    print ("*******有旧文件")
                    self.client.send("old".encode('utf-8'))
                    print("*******发出去了旧文件")
                    recv_size=os.path.getsize(former_path)
                    with open(former_path, 'ab') as f:
                        f.seek(0,2)
                        n=f.tell()
                        n_json = json.dumps(n)
                        n_bytes = n_json.encode('utf-8')
                        self.client.send(struct.pack('i', len(n_bytes)))
                        self.client.send(n_bytes)
                        while recv_size < filesize:
                            line = self.client.recv(1024)
                            recv_size += len(line)
                            f.write(line)
                    if os.path.exists(filepath):
                        overwrite(filepath, former_path, server_md5)
                    else:
                        os.rename(former_path,filepath)
                        if md5sum(filepath) == server_md5:
                            print ('===>下载成功')
                        else:
                            print ('===>下载失败')
                else:
                    print("*******无旧文件")
                    self.client.send("new".encode('utf-8'))
                    print("*******发出去了")
                    # 3、再收真实的数据
                    with open(aliaspath, 'wb') as f:
                        recv_size = 0
                        while recv_size < filesize:
                            line = self.client.recv(1024)
                            recv_size += len(line)
                            f.write(line)
                    if os.path.exists(filepath):
                        overwrite(filepath, aliaspath, server_md5)
                    else:
                        os.rename(aliaspath,filepath)
                        if md5sum(filepath) == server_md5:
                            print ('===>下载成功')
                        else:
                            print ('===>下载失败')
            else:
                print ("无此文件")
        def put(self):
            pass
    def overwrite(filepath,aliaspath,server_md5):
        while True:
            choice = input("文件已存在,是否覆盖(Y/N):")
            if choice == "Y":
                os.remove(filepath)
                os.rename(aliaspath, filepath)
                if md5sum(filepath) == server_md5:
                    print('===>下载成功')
                else:
                    print('===>下载失败')
                break
            elif choice == "N":
                nickname = input("重命名下载文件:")
                if not nickname: continue
                nickpath = os.path.join(DOWNLOAD_DIR, nickname)
                os.rename(aliaspath, nickpath)
                if md5sum(nickpath) == server_md5:
                    print('===>下载成功')
                else:
                    print('===>下载失败')
                break
    
    if __name__ == '__main__':
        client=FtpClient('127.0.0.1',8081)
        client.interactive()
  • 相关阅读:
    where T: class的解释
    调用钉钉的WebAPI接口实现与ERP数据的同步
    Json序列化和反序列化的方式
    Log4Net日志处理
    MVC项目中异常处理
    FindBI商业智能报表工具
    权限列表实现
    委托,匿名,lambda
    [经典贪心算法]贪心算法概述
    [zt]手把手教你写对拍程序(PASCAL)
  • 原文地址:https://www.cnblogs.com/shangdelu/p/8408658.html
Copyright © 2011-2022 走看看