FTP即文件傳輸協(xié)議;它基于客戶機(jī)-服務(wù)器模型體系結(jié)構(gòu),應(yīng)用廣泛。它有兩個(gè)通道:一個(gè)命令通道和一個(gè)數(shù)據(jù)通道。命令通道用于控制通信,數(shù)據(jù)通道用于文件的實(shí)際傳輸。使用FTP可以做很多事情,比如移動(dòng)、下載、復(fù)制文件等。
server端:centos 7 python-3.6.2
客戶端:Windows 7 python-3.6.2 pycharm-2018
程序目的:1、學(xué)習(xí)使用socketserver實(shí)現(xiàn)并發(fā)處理多個(gè)客戶端。
2、了解使用struct解決TCP粘包。
(本人菜鳥一枚,對(duì)于開發(fā)規(guī)范,接口設(shè)計(jì)完全不懂,完全是隨心所欲,自娛自樂。寫博客主要是記錄自己學(xué)習(xí)的點(diǎn)點(diǎn)滴滴,如有不足之處還請(qǐng)見諒。)
1.1 目錄結(jié)構(gòu)如下:
1.2 目錄簡(jiǎn)介:
FTP_SERVER:程序主目錄
app:程序主邏輯目錄,目錄下有四個(gè)模塊:
FTPserver.py:FTP Server端啟動(dòng)入口。
login.py:認(rèn)證注冊(cè)模塊,用于處理用戶注冊(cè),登錄認(rèn)證。
dataAnalysis.py:命令解析模塊,負(fù)責(zé)解析,執(zhí)行客戶端命令。
FileOpertion.py:負(fù)責(zé)文件讀,寫。數(shù)據(jù)發(fā)送,數(shù)據(jù)接收。
db:存放user_pwd.db文件,用于存放用戶信息(用戶名,密碼,F(xiàn)TP目錄總空間,已使用空間等)
lib:存放公共數(shù)據(jù)。
1.3 模塊中類的繼承關(guān)系
1.4 執(zhí)行流程
1.4.1 程序啟動(dòng)文件FTPserver.py,程序啟動(dòng)后進(jìn)入監(jiān)聽狀態(tài)。核心代碼如下:
class MyFtpServer(socketserver.BaseRequestHandler): def handle(self): # 重寫handle方法,處理socket請(qǐng)求 print(f"連接來自{self.client_address}的客戶端") commom_obj = Commom() data_analy = DataAnalysis() login_obj = Login() while 1: # 執(zhí)行用戶選項(xiàng):1、登陸系統(tǒng) 2、注冊(cè)賬號(hào)。并返回一個(gè)結(jié)果 status_id = login_obj.run_client_choice(self.request, commom_obj) if status_id == "01": # 登陸成功 if not self.run_ftp_server(data_analy,commom_obj): # 執(zhí)行ftpserver主功能 break elif int(status_id) == -1: # client斷開連接了 break print(f"客戶端{(lán)self.client_address}斷開了連接") def run_ftp_server(self,data_analy,commom_obj): """" 登陸成功后,接收客戶端發(fā)來的命令,并進(jìn)行處理 :param data_analy:負(fù)責(zé)解析,執(zhí)行客戶端命令的對(duì)象 :param commom_obj:程序執(zhí)行時(shí)所需的數(shù)據(jù)對(duì)象 :return 返回false代表客戶端斷開連接了 """ while True: try: cmd_len_pack = self.request.recv(4) cmd_len = struct.unpack('i',cmd_len_pack)[0] # 獲取命令長(zhǎng)度,防止粘包 except Exception: break recv_data = self.request.recv(cmd_len).decode('utf-8') # 接收客戶端數(shù)據(jù) if recv_data.upper() == "Q": # 客戶端提出斷開連接了 break # 解析,處理客戶端的命令 data_analy.syntax_analysis(recv_data, self.request, commom_obj) return Falseif __name__ == '__main__': print('運(yùn)行FTP服務(wù)') ip_port = ('192.168.10.10',9000) # 創(chuàng)建并發(fā)服務(wù)端對(duì)象 server = socketserver.ThreadingTCPServer(ip_port, MyFtpServer) # 開啟服務(wù) server.serve_forever()
新聞熱點(diǎn)
疑難解答
圖片精選