preamble
When downloading a file, you are most afraid of being disconnected in the middle and not being able to download the complete file successfully. With Breakpoint Transfer, you can pick up the file where it left off without having to re-download it. This feature is very useful for downloading larger files. So this article will share with you how to use python to implement a ftp program that can be disconnected and concurrent.
I. Requirements
1、User md5 authentication
2、Support multiple users to log in at the same time (concurrent)
3, enter the user's command line mode, support cd switch directory, ls view directory subfiles
4. Execute the command (ipconfig)
5. Transmission of documents:
a. Support breakpoint continuous transmission
b. Progress bar displayed during transmission
II. Thoughts
1. Client user login and registration:
a. The client only provides a user name and password, choosing to log in or register.
b. The server side registers and writes the encrypted password into the file, and finally returns to the client whether the login or registration is successful.
and cd commands
a. The client enters the command, the server side processes it and returns it to the client.
3. Execute the order:
a. The client sends the command to be executed
b, the server side to execute the command, and return to the client needs to receive the number of times the command s = r [0] +1, where r = divmod (the total length of the results, 1024)
c. Number of times the client has received it, telling the server that it has received it
d. The server sends the result of the execution, and the client receives the result in a for loop.
4. Sending documents:
a. The client inputs the file path (the beta path is:), sends the file name and file size
b, the server detects whether the specified directory contains the file, if not, return to the client string s, that is, from the beginning to send start, has_recv = 0
If there is, i.e., you need to break the upload, return to the client how many has_recv have been uploaded
c. The client receives the return value and searches to the location of has_recv, sends and receives in a loop, and prints the current progress until the transmission is complete.
Note: This program can cycle through user-selected file transfers and execution commands
III. Codes
Configuration file:
#!/usr/bin/env python # -*- coding: utf-8 -*- import os BASE_DIR = ((__file__)) The upper directory of the # configuration file NEW_FILENAME=(BASE_DIR,'view') # New file directory NAME_PWD=(BASE_DIR,'db','name_pwd') # Username and password directory USER_FILE=(BASE_DIR,'db')
Server-side:
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys,os import time import socket import hashlib import pickle import subprocess import socketserver (((__file__))) from config import settings new=settings.NEW_FILENAME class Myserver(): def recv_file(self): ''' File Transfer :return. ''' conn= a=str((1024),encoding='utf-8') file_size,file_name=(',') new_file_name=(new,file_name) if file_name in new: #Detect if a file already exists, involves broken transfers has_recv=(new).st_size # Calculate temporary file size (bytes(has_recv,encoding='utf-8')) with open(new_file_name,'ab') as f: #Additional mode while has_recv<=int(file_size): data=(1024) (data) has_recv+=len(data) else: has_recv=0 (bytes('s',encoding='utf-8')) # Client receives string s, sends from 0 with open(new_file_name,'wb') as f: while has_recv<=int(file_size): data=(1024) (data) has_recv+=len(data) def command(self): ''' Execute the command :return. ''' conn= a=(1024) ret=str(a,encoding='utf-8') ret2 = subprocess.check_output(ret, shell=True) r=divmod(len(ret2),1024) s=r[0]+1 # of times the client needs to receive (bytes(str(s),encoding='utf-8')) (1024) # of acknowledgements received by the client that need to be received (ret2) def md5(self,pwd): ''' Encrypt the password :param pwd: password :return. ''' hash=hashlib.md5(bytes('xx7',encoding='utf-8')) (bytes(pwd,encoding='utf-8')) return () def login(self,usrname,pwd): ''' Login :param usrname: username :param pwd: password :return:Whether the login succeeded or not ''' conn= s=(open(settings.NAME_PWD,'rb')) if usrname in s: if s[usrname]==self.md5(pwd): # Compare with encrypted passwords return True else: return False else: return False def regist(self,usrname,pwd): ''' Register :param usrname: username :param pwd: password :return:Whether registration was successful or not ''' conn= s=(open(settings.NAME_PWD,'rb')) if usrname in s: return False else: s[usrname]=self.md5(pwd) mulu=(settings.USER_FILE,usrname) (mulu,'a') (s,open(settings.NAME_PWD,'wb')) return True def before(self,usrname,pwd,ret): ''' Determine registration and login, and display the user's detailed directory information, support cd and ls commands :return. ''' conn= if ret=='1': r=(usrname,pwd) if r: (bytes('y',encoding='utf-8')) else: (bytes('n',encoding='utf-8')) elif ret=='2': # print(usrname,pwd) r=(usrname,pwd) if r: (bytes('y',encoding='utf-8')) else: (bytes('n',encoding='utf-8')) def usr_file(self,usrname): ''' Show user's detailed directory information, support cd and ls commands :param usrname: username :return. ''' conn= (1024) mulu=(settings.USER_FILE,usrname) (bytes(mulu,encoding='utf-8')) while True: b=(1024) ret=str(b,encoding='utf-8') try: a,b=(' ',1) except Exception as e: a=ret if a=='cd': if b=='..': mulu=(mulu) else: mulu=(mulu,b) (bytes(mulu,encoding='utf-8')) elif a=='ls': ls=(mulu) print(ls) a=','.join(ls) (bytes(a,encoding='utf-8')) elif a=='q': break def handle(self): conn= (bytes('welcome',encoding='utf-8')) b=(1024) ret=str(b,encoding='utf-8') print(ret) (bytes('b ok',encoding='utf-8')) c=(1024) r=str(c,encoding='utf-8') usrname,pwd=(',') (usrname,pwd,ret) #Login or Registration Verification self.usr_file(usrname) # Show user's detailed directory information, support cd and ls commands while True: a=(1024) (bytes('Received a',encoding='utf-8')) ret=str(a,encoding='utf-8') if ret=='1': self.recv_file() # (bytes('file ok',encoding='utf-8')) elif ret=='2': () elif ret=='q': break else: pass if __name__=='__main__': sever=(('127.0.0.1',9999),Myserver) sever.serve_forever()
Client:
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys import time import os import socket (((__file__))) from config import settings def send_file(file_path): ''' Send file :param file_name:file name :return. ''' size=(file_path).st_size file_name=(file_path) (bytes(str(size)+','+file_name,encoding='utf-8')) # Send file size and file name ret=(1024) # Receive how much has been passed r=str(ret,encoding='utf-8') if r=='s': # File does not exist, pass it from the beginning has_send=0 else: # file exists has_send=int(r) with open(file_path,'rb') as f: (has_send) #Locate to a location that has already been transmitted while has_send<size: data=(1024) (data) has_send+=len(data) ('\r') # Empty the contents of the file (0.2) ('Sent %s%%|%s' %(int(has_send/size*100),(round(has_send/size*40)*'★'))) () #Forced swipe out of memory print("Upload successful\n") def command(command_name): ''' Execute the command :param command_name. :return. ''' (bytes(command_name,encoding='utf-8')) ret=(1024) # of times a receive command needs to be received (bytes('Number of times received',encoding='utf-8')) r=str(ret,encoding='utf-8') for i in range(int(r)): # need to receive int(r) a total of times ret=(1024) # Waiting for the client to send r=str(ret,encoding='GBK') print(r) def login(usrname,pwd): ''' Login :param usrname:username :param pwd:password :return:Successful login or not ''' (bytes(usrname+','+pwd,encoding='utf-8')) ret=(1024) r=str(ret,encoding='utf-8') if r=='y': return 1 else: return 0 def regist(usrname,pwd): ''' Register :param usrname:username :param pwd:password :return:Whether registration was successful or not ''' (bytes(usrname+','+pwd,encoding='utf-8')) ret=(1024) r=str(ret,encoding='utf-8') if r=='y': return 1 else: return 0 def before(usrname,pwd): ''' Select login or register, show user's detailed directory information, support cd and ls commands :return. ''' a=input('Please select 1.Login 2.Register') (bytes(a,encoding='utf-8')) (1024) if a=='1': ret=login(usrname,pwd) if ret: print('Login successful') return 1 else: print('Username or password error') return 0 elif a=='2': ret=regist(usrname,pwd) if ret: print('Registration Successful') return 1 else: print('User name already exists') return 0 def usr_file(usrname): (bytes('Print user file path',encoding='utf-8')) ret=(1024) # Waiting for the client to send r=str(ret,encoding='utf-8') print(r) while True: a=input('Type cd to switch directories, ls to view directory details, q to exit>:') (bytes(a,encoding='utf-8')) if a=='q': break else: ret=(1024) # Waiting for the client to send r=str(ret,encoding='utf-8') if len(r)==1:# Determine if it's a cd result or an ls result (ls with only one subdirectory can also be printed directly) print(r) else: li=(',') for i in li: print(i) # Print every subdirectory def main(usrname,pwd): ret=(1024) # Waiting for the client to send r=str(ret,encoding='utf-8') print(r) result=before(usrname,pwd)#Login or Register if result: usr_file(usrname) while True: a=input('Please choose 1. to pass a file 2. to execute a command q to exit:') (bytes(str(a),encoding='utf-8')) ret=(1024) # Confirmation of receipta r=str(ret,encoding='utf-8') print(r) if a=='1': b=input('Please enter the file path (beta path is:):') # b='' if (b): send_file(b) (bytes('hhe',encoding='utf-8')) # (1024) elif a=='2': b=input('Please enter command:') command(b) elif a=='q': break else: print('Input error') () if __name__ == '__main__': obj=() # Create a client socket object (('127.0.0.1',9999)) usrname=input('Please enter a user name') pwd=input('Please enter your password') main(usrname,pwd)
summarize
Above is the python implementation can be intermittent and concurrent ftp program all, the article describes the details, I hope you learn or use python to bring some help.