您好,登錄后才能下訂單哦!
分為服務端和客戶端,要求可以有多個客戶端同時操作。
客戶端可以查看服務器文件庫中有什么文件。
客戶端可以從文件庫中下載文件到本地。
客戶端可以上傳一個本地文件到文件庫。
使用print在客戶端打印命令輸入提示,引導操作
服務端
# 導入相關模塊 from socket import * from multiprocessing import Process import signal, os, time # 綁定IP地址 IP = "127.0.0.1" # 綁定端口 PORT = 8888 ADDR = (IP, PORT) # 綁定服務器的指定目錄 DIR = "/home/max/ftp" # 處理查看文件請求 def browse(c): # 列表方式查看文件 list = os.listdir("%s" % DIR) # 按通信協議格式組織數據 msg = "B " + ";".join(list) # 發送到客戶端 c.send(msg.encode()) # 處理客戶端下載文件請求 def download(c, file): # 判斷文件是否存在且是否是文件 if file in os.listdir(DIR) and os.path.isfile("%s/%s" % (DIR, file)): # 打開文件 f = open("%s/%s" % (DIR, file), "rb") # 發送下載代碼,告知客戶端進入"D" c.send(("D %s " % file).encode()) # 等待客戶端先進入"D"模式下的recv阻塞函數 time.sleep(0.1) # 循環發送文件 while True: data = f.read(1000) if not data: # 設置間隔,等待文件傳輸完整 time.sleep(0.1) # 約定的信息讓客戶端退出接收循環 c.send(b"finished") break c.send(data) f.close() # 否則按協議格式發送錯誤代碼 else: c.send(b"D fileerror ") # 處理客戶端上傳文件請求 def upload(c, file): # 創建文件 f = open("%s/%s" % (DIR, file), "wb") # 循環接收文件 while True: data = c.recv(1024) # 收到約定的信息退出循環 if data == b"finished": break f.write(data) f.close() # 處理客戶端退出請求 def login_out(c): # 按協議格式組織信息 msg = "O closed " # 發給客戶端的recv_msg進程 c.send(msg.encode()) def deal(c): # 發送代碼告知客戶端連接成功 c.send(b"K ") while True: # 循環接收客戶端請求,約定通信協議為"* ** ****"格式 msg = c.recv(1024) # 如果客戶端崩了,解除該子進程 if not msg: break # 解析請求 req = msg.decode().split(" ", 2) # 處理查看文件請求,跳入browse函數 if req[0] == "B": browse(c) # 處理客戶端下載文件請求,跳入download函數 elif req[0] == "D": download(c, req[1]) # 處理客戶端上傳文件請求,跳入upload函數 elif req[0] == "U": upload(c, req[1]) # 處理客戶端退出請求,跳入login_out函數 elif req[0] == "O": login_out(c) # 跳出循環,結束子進程 break # 主程序,父進程用于接收客戶端請求并循環創建子進程,子程序處理請求 def main(): # 創建tcp套接字 s = socket() # 綁定服務器地址 s.bind(ADDR) # 設置監聽套接字 s.listen() # 處理僵尸進程 signal.signal(signal.SIGCHLD, signal.SIG_IGN) while True: # 連接客戶端 c, addr = s.accept() # 創建子進程,用以處理客戶端請求,跳入deal函數 p = Process(target=deal, args=(c,)) # 子程序開始執行 p.start() if __name__ == '__main__': main()
客戶端
# 導入相關模塊 from socket import * import os, sys, time # 綁定服務端IP地址 IP = "127.0.0.1" # 綁定服務端端口 PORT = 8888 ADDR = (IP, PORT) # 收到約定的信息退出循環 # 發送消息進程 def send_msg(s): # 等待接收進程先運行到"K"分支 time.sleep(0.1) while True: try: # 輸入指令 data = input(">>>") except: # 客戶端錯誤,向服務端發送O data = "O" if data == "B": # 查看目錄 msg = "B " s.send(msg.encode()) elif data == "D": # 下載文件 # 輸入想要下載的文件 want = input("download ? file:") msg = "D %s " % want s.send(msg.encode()) elif data == "U": # 上傳文件 file = input("upload ? file:") # 判斷文件是否在客戶端文件所在的目錄且是文件 if file in os.listdir(os.getcwd()) and os.path.isfile("%s/%s" % (os.getcwd(), file)): msg = "U %s " % file s.send(msg.encode()) f = open("%s" % file, "rb") # 等待服務端進入upload的recv阻塞函數 time.sleep(0.1) while True: data = f.read(1000) if not data: # 設置間隔,等待文件傳輸完整 time.sleep(0.1) # 約定的信息讓客戶端退出接收循環 s.send(b"finished") break s.send(data) f.close() print("upload succussfully") # 否則按協議格式顯示錯誤代碼 else: print("file not exist\ninput BDUO to forward\n", end="") elif data == "O": # 斷開連接 msg = "O " s.send(msg.encode()) sys.exit() # 指令錯誤 else: print("input error") # 接收消息進程 def recv_msg(s): while True: data = s.recv(1024) # 解析數據 msg = data.decode().split(" ", 2) if msg[0] == "K": # 登錄成功反饋 print( "login in successfully\ninput B to browse,D to download,U to upload,O to login out") elif msg[0] == "B": # 查看目錄反饋 # 如果文件庫不為空 if msg[2]: print("files:", msg[2], "\n>>>", end="") else: print("files: no files", "\n>>>", end="") elif msg[0] == "D": # 服務端文件不存在 if msg[1] == "fileerror": print("file not exist\ninput BDUO to forward\n>>>", end="") continue # 服務端文件存在 else: f = open("%s" % msg[1], "wb") while True: data = s.recv(1024) # 收到約定的信息退出循環 if data == b"finished": break f.write(data) f.close() print("download successfully\n>>>", end="") elif msg[0] == "O": # 收到來自發送消息進程發送到服務端的斷開請求 # 進程退出并打印提示 sys.exit("login out successfully") # 主程序 def main(): # 創建tcp套接字 s = socket() # 連接服務端 s.connect(ADDR) # 創建多進程,子進程用于發送消息,父進程用于接收消息 pid = os.fork() if pid < 0: print("system error") # 子進程 elif pid == 0: send_msg(s) # 父進程 else: recv_msg(s) if __name__ == '__main__': main()
總結
以上所述是小編給大家介紹的Python_模擬FTP文件服務器的操作方法,希望對大家有所幫助,也非常感謝大家對億速云網站的支持!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。