First, the operation requirements
Develop a simple ftp:
1. User Login
2. Upload/download files
3. Different User home directories
4. View the files in the current directory
5. Full use of object-oriented knowledge
Ii. Description of the program directory
ftp/|--ftpclient/ #客户端文件夹 | | --Sample Folder/ #客户端上传/Download Sample folder | | --client_start.py #客户端启动程序 | | --ftpserver/ #服务端文件夹 | | --bin/| | | --__init__.py| | | --server_start.py #程序启动的主入口 | | | | --conf/| | | --setting.py #配置文件 | | | | --db/ #用户数据 | | | --Alex #用户名alex的数据文件夹 | | | --Japhi #用户名japhi的数据文件夹 | | | | --home/| | | --alex/ #用户alex用户家目录 | | | --japhi/ #用户japhi用户家目录 | | | --log/| | --Log_sys.log #日志文件 (not enabled) | | --src/| | --__init__.py| | --common.py #公共功能 | | --server_start.py #程序启动的主入口 | | --user.py #用户类及方法 | | --Ftp.png #流程图 |--README.txt
Third, flow chart
Iv. Code of operation
1. Client Launcher client_start.py under FtpClient Client folder:
Import Socket,os,sys,timebasedir = Os.path.join (Os.path.dirname (Os.path.dirname (Os.path.abspath)), " Ftpserver ") Updir = Os.path.join (Os.path.dirname (Os.path.abspath (__file__))," Sample Folder ") Sys.path.append (Basedir) from Conf import settingsdef Upload (client,user_info,name): "Client uploads a file function:p Aram Client:scoket client flag:p Aram User_in FO: Client Login user's information:p Aram Name: Client Login user name: Return:none "Print (" \033[1;37m currently selectable upload \033[0m ". Center (+," * ")) dic = {} for root, dirs, files in Os.walk (Updir): For i,j in Enumerate (files): K = i+1 Dic[k] = J Print ("\033[1;37m%s:%s\033[0m"% (k,j)) choice = input ("Please enter the file number to be uploaded:>>>") command = "upload+" +u ser_info+ "+" +dic[int (choice)] Client.sendall (bytes (command,encoding= "Utf-8") res = CLIENT.RECV (1024x768) if STR (res, encoding= "utf-8") = = "True": dir = Os.path.join (updir,dic[int (choice)]) with open (dir, "RB") as F: data = F.read () a = str (len (data)) Client.sendall (Bytes (a,encoding= "Utf-8")) Client.sendall (data) time.sleep (0.5) Print ("\033[1;37m file Upload succeeded \033[0m") def download (client,user_info,name): "Client download file function:p Aram Client:scoket client Flag :p Aram user_info: Client Login user Information:p Aram Name: Client login Username: Return:none ' dic = {} command = ' download+ ' +user _info client.sendall (bytes (command, encoding= "Utf-8")) data = CLIENT.RECV (4069) res = eval (str (data, encoding= "UT F-8 ")) If Len (res) = = 0:print (" \033[1;31m no file \033[0m in current directory ". Center (+,"-")) Else:for i,j in Enumerat E (res): K = i + 1 Dic[k] = J Print ("\033[1;37m%s:%s\033[0m"% (k, j)) Choice = InP UT ("Please select the file number to download:>>>") cm = "downloadfile+" +dic[int (choice)]+ "+" +name client.sendall (bytes (cm, encod ing= "Utf-8")) print ("\033[1;37m ready to start download file \033[0m") dir = Os.path.join (Updir, Dic[int (choice)]) Res_leng th = str (CLIENT.RECV (1024). Decode ()) length = 0 with open (dir, "WB") as F:while True:data = CLIENT.RECV ( 1024x768) Length + = Len (data) f.write (data) if length >= int (res_length): Print ("\033[1;37m file download succeeded \033[0m") time.sleep (0.5) Breakdef view_file ( Client,user_info,name): "Client view the function of the file in the current directory:p Aram client:scoket client flag:p Aram User_info: Client logged on user information:p Aram Name: Client login Username: return:none "command =" view+ "+user_info client.sendall (bytes (command,encoding=" Utf-8 ")) data = CLIENT.RECV (1024x768) res = eval (str (data,encoding= "Utf-8")) If Len (res) = = 0:print ("\033[1;31m current directory temporarily No file \033[0m ". Center (+,"-")) Else:for I in Res:print (" \033[1;35m%s\033[0m "%i) def operate (Client,use R_info,name): "Client operation main function:p Aram Client:scoket client flag:p Aram user_info: Client Login user Information:p Aram Name: Client Login user Name : Return:none " DIC = {"1": Upload, "2":d ownload, "3": view_file} info = "------Operation instruction------1, upload file 2, download file 3, view directory under File 4, exit "While True:print (" \033[1;33m%s\033[0m "% info) choice = input (" Please enter the command you want to manipulate:>>> "). Strip () If Choice.isdigit () and 0 < int (choice) <= len (DIC): Dic.get (choice) (Client,user_info,name) E Lif int (choice) = = 4:break Else:print ("\033[1;31m output error \033[0m". Center (+, "-")) def Com_parse (client,com): "Client user login Registration hit resolution function:p Aram client: Clients scoket flag:p Aram com: command: return: Login Successful return true, otherwise false "# Print (COM) client.sendall (bytes (com,encoding=" Utf-8 ")) Re = CLIENT.RECV (4096) if Str (re,encoding=" Utf-8 ") = = "Success": Return True elif str (RE, encoding= "utf-8") = = "Success": Return falsedef Login (client,dat A): "Client User Login function:p Aram client: Scoket flag:p Aram Data: Return:none" "name = input (" Please enter your name: >>> "). Strip () PSD = input ("Please enter password:>>>"). Strip () User_info = name+ "+" +psd com = "login+" +user_info if Com_parse (client , COM): Operate (client,user_info,name) Else:print ("\033[1;31m landed abnormally \033[0m") def Register (Client,data): ' Client user Registration function:p Aram client: Scoket flag:p Aram Data: Return:none ' name = input ("Please enter your name: >&G T;> "). Strip () PSD = input (" Please enter password:>>> "). Strip () com =" register+ "+ name +" + "+ PSD if Com_parse (Clie NT, com): User_info = name + "+" + PSD print ("\033[1;31m registered successfully \033[0m") command = "view+" + user_info Client.sendall (bytes (command, encoding= "Utf-8")) Res1 = CLIENT.RECV (1024x768) Operate (client, User_info, n AME) Else:print ("\033[1;31m registered Exception \033[0m") def Quit (client,data): "' Program Exit Function:p Aram client: Scoket flag :p Aram Data: Return:none "exit () def main_func (client,data):" Client main Menu function:p Aram Client: Customer End Scoket Flag:p Aram Data: Data: Return:none "dic = {" 1 ": Login," 2 ": Register," 3 ": quit} info =" '------User Login interface------*{0}* 1, Login 2. Registration 3, Exit "". Format (str (data,encoding= "Utf-8")) print ("\033[1;33m%s\033[0m"%info) what = input ("You're going to do Why >>> "). Strip () if What.isdigit () and 0 < int (what) <= len (DIC): Dic.get (What) (Client,data) Else : Print ("\033[1;31m output error \033[0m". Center (+, "-")) if __name__ = = ' __main__ ': client = Socket.socket (Socket.af_inet, Socket. SOCK_STREAM) client.connect ("localhost", settings. PORT) Main_func (CLIENT,CLIENT.RECV (1024x768)) Client.close ()
2, Ftpserver server file under the Conf file Configuration program settings.py:
Import Osbasedir = Os.path.dirname (Os.path.dirname (Os.path.abspath (__file__))) User_home = "%s/home"%basediruser_ info = "%s/db"%basedirhost = "0.0.0.0" PORT = 9999
3, Ftpserver server file under the src file under the Public function program common.py:
Import logging,os,pickle,sys,uuidframe = Os.path.dirname (Os.path.dirname (Os.path.abspath (__file__))) Sys.path.append (frame) # from conf import setting## def sys_logging (content,levelname): # "# program logging function #:p Aram Content: The contents of the log #:p Aram LevelName: Level of Log #: return:none# ' # _filename = Os.path.join (Setting.log_dir, "log _sys.log ") # log = Logging.getlogger (_filename) # logging.basicconfig (filename=_filename,level=logging.info,format= ' % (asctime) s-% (levelname) s-% (message) s ', datefmt= '%m/%d/%y%i:%m:%s%p ') # if LevelName = = ' Debug ': # Logging.deb UG (content) # elif LevelName = = ' Info ': # logging.info (content) # elif levelname = ' warning ': # Loggi Ng.warning (content) # elif LevelName = = ' ERROR ': # logging.error (content) # elif LevelName = ' critical ': # Logging.critical (content) def show (Msg,msg_type): "' Program different information print font color:p Aram msg: Print information:p Aram Msg_type: Print the letter Type of interest: Return:none "if msg_type = = "Info": show_msg = "\033[1;35m%s\033[0m"%msg elif msg_type = "Error": show_msg = "\033[1;31m%s\033[0m"% msg elif Msg_type = = "MSG": show_msg = "\033[1;37m%s\033[0m"%msg else:show_msg = "\033[1;32m%s\033[0m "%msg Print (show_msg)
Src folder under server_start.py Server start main function:
Import Socket,os,sysbase_dir = Os.path.dirname (Os.path.dirname (Os.path.abspath (__file__))) Sys.path.append (base_ DIR) from conf import settingsfrom Common import showfrom User import Userdef fuck_tcp (con,addr): "' Server-side data parsing main function: Param con::p Aram Addr:: Return: "Show (" received {0} connection request, in communication ...) ". Format (addr)," info ") Con.sendall (bytes (" Connection succeeded ", encoding=" Utf-8 ")) while True:cmd = CON.RECV (4096) if Not cmd:break else: # try:data = str (Cmd.decode (encoding= "Utf-8")) R ES = data.split ("+") if res[0] = = "Login": Show ("Incoming client login request, logging in ...) "," msg ") name = res[1] psd = res[2] user = User (name, PSD) si GN = User.login () if Sign:con.sendall (bytes ("Success", encoding= "Utf-8")) Else:con.sendall (Bytes ("Failure", encoding= "Utf-8")) elif res[0] = = "Register": Show ("Receiving client registration request, registering ... "," msg ") name = res[1] psd = res[2] user = User (name, PSD) if User.register (): Con.sendall (bytes ("Success", encoding= "Utf-8")) Else: Con.sendall (Bytes ("Failure", encoding= "Utf-8")) elif res[0] = = "View": Show ("Received client Create or view current directory file The request ... "," msg ") name = res[1] psd = res[2] user = User (name, PSD) re s = user.view_file () file = str (res) con.sendall (bytes (file, encoding= "Utf-8")) Show ("Current directory file View or create success", "info") elif res[0] = = "Upload": Show ("Request to receive client upload file ... "," msg ") name = res[1] filename = res[3] Con.sendall (bytes (" True ", encoding=" Utf-8 ")) Res_length = str (CON.RECV (1024x768). Decode ()) user.receive (filename,name,res_lengtH,con) elif res[0] = = "Download": Show ("Request to receive client download file ... "," msg ") name = res[1] psd = res[2] user = User (name, PSD) re s = user.view_file () file = str (res) con.sendall (bytes (file, encoding= "Utf-8")) E Lif res[0] = = "DownloadFile": Show ("Start download File", "MSG") User.download_file (Res[1], res[2], con) Show ("File download succeeded", "info") if __name__ = = ' __main__ ': Server = Socket.socket (socket.af_inet,socket. SOCK_STREAM) server.bind ("localhost", settings. Port) Server.listen (5) Show ("Listening for [%s] address [%s] port, waiting for connection ... "% (settings. Host,settings. PORT), "info") Con,addr = Server.accept () fuck_tcp (CON,ADDR)
Src file under User class program user.py:
Import Os,sys,pickle,socket,timebase_dir = Os.path.dirname (Os.path.dirname (Os.path.abspath (__file__))) Sys.path.append (Base_dir) from conf import settingsfrom Common import Showclass User (object): ' User class ' Def _ _init__ (SELF,USERNAME,PSD): Self.name = Username Self.password = PSD Self.home_path = Settings.user_h ome + "/" +self.name def login (self): ' User Login method: return: ' ' user_dic = User.info_r EAD (Self.name) if User_dic.get (self.name) = = Self.password:show ("Login Successful", "info") return True Else:show ("Login failed, user name or password wrong", "error") return False def Register (self): "' User registration Method: return: ' dic = {} Dic[self.name] = Self.password if User.info_write (self.name,di c): Show ("Registration succeeded", "info") return True else:show ("Registration failed", "error") return F Alse def view_file (self): "' View files under current directory: return: List of filenames under directory "if not os.path.exists (Self.home_path): Os.mkdir (self . Home_path) with open ("%s\ blank file"%self.home_path, "W") as F:f.write ("Blank file") for Root, dirs, Files in Os.walk (Self.home_path): Return files @staticmethod def download_file (Filename,name,con): "Download file static method:p Aram FileName: file name:p Aram Name: User name:p Aram Con: flag: Return:none "DIR = Os.path.join (Os.path.join (Os.path.join (Base_dir," Home "), name), filename) with open (dir," RB ") a s f: # while True:data = F.read () a = str (len data) # Print (Type (a)) Con.sendall (Bytes (a,encoding= "Utf-8")) Con.sendall (data) @staticmethod def receive (Filename,name,res_ Length,con): "Receive file static method:p Aram FileName: file name:p Aram Name: username:p Aram Con: flag: Return:none "" dir = Os.path.join (Os.path.join (Os.path.join (Base_dir, "Home"), name), filename) length = 0 f = open (di R, "WB") While True:data = Con.recv (1024x768) Length + = Len (data) f.write (data) # print (length) if length = = Int (res_length): Show ("File download succeeded", "info") F.flush () F.close () return True @staticmethod def info_read (name): "The static reading of user data State method:p Aram Name: Username: return: dictionary "user_dir = Os.path.join (settings.user_info,name) I F os.path.exists (User_dir): With open (User_dir, "RB") as F:dic = Pickle.load (f) r Eturn dic else:print ("User data is empty") @staticmethod def info_write (name,dic): "The static of writing user data :p Aram Name: User name:p Aram dic: User Information Dictionary: return:true "user_dir = Os.path.join (settings . User_info, name) With open (User_dir, "WB") as F:pickle.dump (dic,f) return True
Five, the Program interface description
Python Road-Jobs: Developing Simple FTP