亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Python之路【第十五篇】開發FTP多線程程序

系統 2093 0
            
              要求:

            
            1
            
              .用戶加密認證

            
            2
            
              .允許同時多用戶登錄

            
            3
            
              .每個用戶有自己的家目錄,且只能訪問自己的家目錄

            
            4
            
              .對用戶進行磁盤配額,每個用戶的可用空間不同

            
            5
            
              .允許用戶在ftp server上隨意切換目錄

            
            6
            
              .允許用戶查看當前目錄下的文件

            
            7
            
              .允許上傳和下載文件,并保證文件的一致性md5

            
            8
            
              .文件傳輸過程中顯示進度條

            
            9.支持文件的斷點續傳
          
          
            使用:
          
          
1.啟動ftp_server.py
2.創建用戶,輸入:用戶名(默認密碼是zhurui)
3.啟動FTP服務器
4.啟動客戶端ftp_client.py
5.輸入用戶名和密碼:alex zhurui | william zhurui
6.與服務器server交互:

???? Python之路【第十五篇】開發FTP多線程程序_第1張圖片

?

server服務端

bin下的文件?

ftp_server.py

            
              #
            
            
              _*_ coding:utf-8 _*_
            
            
              
#
            
            
              Author :simon
            
            
              import
            
            
               os

            
            
              import
            
            
               sys

BASE_DIR 
            
            = os.path.dirname(os.path.dirname(os.path.abspath(
            
              __file__
            
            
              )))

sys.path.append(BASE_DIR)


            
            
              from
            
             core.main 
            
              import
            
            
               Manager


            
            
              if
            
            
              __name__
            
             == 
            
              '
            
            
              __main__
            
            
              '
            
            
              :
    Manager().run()
            
          

conf下的文件

accounts.ini(這個可以在執行中創建)

            
              [william]
password 
            
            =
            
               39da56d2e7a994d38b9aaf329640fc6e
homedir 
            
            = home/
            
              william
quota 
            
            = 10
            
              

[zhurui]
password 
            
            =
            
               39da56d2e7a994d38b9aaf329640fc6e
homedir 
            
            = home/
            
              zhurui
quota 
            
            = 10
            
              

[simon]
password 
            
            =
            
               39da56d2e7a994d38b9aaf329640fc6e
homedir 
            
            = home/
            
              simon
quota 
            
            = 10
          

settings.py

            
              #
            
            
              _*_ coding:utf-8 _*_
            
            
              
#
            
            
               Author:Simon
            
            
              
#
            
            
               Datetime:2019/8/14 11:00
            
            
              
#
            
            
               Software:PyCharm
            
            
              import
            
            
               os
BASE_DIR 
            
            = os.path.dirname(os.path.dirname(os.path.abspath(
            
              __file__
            
            
              )))
ACCOUNTS_FILE 
            
            = os.path.join(BASE_DIR, 
            
              '
            
            
              conf
            
            
              '
            
            , 
            
              '
            
            
              accounts.ini
            
            
              '
            
            
              )

HOST 
            
            = 
            
              '
            
            
              127.0.0.1
            
            
              '
            
            
              
PORT 
            
            = 8080
            
              

MAX_CONCURRENT_COUNT 
            
            = 10
          

core下的文件

main.py

            
              #
            
            
               _*_ coding:utf-8 _*_
            
            
              
#
            
            
              Author:Simon
            
            
              from
            
             core.user_handle 
            
              import
            
            
               UserHandle

            
            
              from
            
             core.server 
            
              import
            
            
               Ftpserver


            
            
              class
            
            
               Manager():
    
            
            
              def
            
            
              __init__
            
            
              (self):
        
            
            
              pass
            
            
              def
            
            
               start_ftp(self):
        
            
            
              '''
            
            
              啟動ftp_server端
            
            
              '''
            
            
              
        server 
            
            =
            
               Ftpserver()
        server.run()
        server.close()

    
            
            
              def
            
            
               create_user(self):
        
            
            
              '''
            
            
              創建用戶
            
            
              '''
            
            
              
        username 
            
            = input(
            
              '
            
            
              請輸入要創建的用戶>:
            
            
              '
            
            
              ).strip()
        UserHandle(username).add_user()

    
            
            
              def
            
            
               quit_func(self):
        quit(
            
            
              '
            
            
              get out...
            
            
              '
            
            
              )

    
            
            
              def
            
            
               run(self):
        msg 
            
            = 
            
              '''
            
            
              \033[31;0m
        1、啟動ftp服務器
        2、創建用戶
        3、退出\033[0m\n
        
            
            
              '''
            
            
              
        msg_dic 
            
            = {
            
              '
            
            
              1
            
            
              '
            
            : 
            
              '
            
            
              start_ftp
            
            
              '
            
            , 
            
              '
            
            
              2
            
            
              '
            
            : 
            
              '
            
            
              create_user
            
            
              '
            
            , 
            
              '
            
            
              3
            
            
              '
            
            : 
            
              '
            
            
              quit_func
            
            
              '
            
            
              }
        
            
            
              while
            
            
               True:
            
            
            
              print
            
            
              (msg)
            num 
            
            = input(
            
              '
            
            
              請輸入數字num>>>>:
            
            
              '
            
            
              ).strip()
            
            
            
              if
            
             num 
            
              in
            
            
               msg_dic:
                getattr(self,msg_dic[num])()
            
            
            
              else
            
            
              :
                
            
            
              print
            
            (
            
              '
            
            
              \033[1;31m請重新選擇\033[0m
            
            
              '
            
            )
          

server.py

            
              #
            
            
              -*- coding:utf-8 -*-
            
            
              
#
            
            
               Author:Simon
            
            
              
#
            
            
               Datetime:2019/8/13 21:02
            
            
              
#
            
            
               Software:PyCharm
            
            
              import
            
            
               os

            
            
              import
            
            
               socket

            
            
              import
            
            
               struct

            
            
              import
            
            
               pickle

            
            
              import
            
            
               hashlib

            
            
              import
            
            
               subprocess

            
            
              import
            
            
               queue

            
            
              from
            
             conf 
            
              import
            
            
               settings

            
            
              #
            
            
               from core.user_handle import UserHandle
            
            
              from
            
             core.user_handle 
            
              import
            
            
               UserHandle


            
            
              from
            
             threading 
            
              import
            
            
               Thread, Lock


            
            
              class
            
            
               Ftpserver():
    MAX_SOCKET_LISTEN 
            
            = 5
            
              
    MAX_RECV_SIZE 
            
            = 8192

    
            
              def
            
            
              __init__
            
            
              (self):
        self.socket 
            
            =
            
               socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.bind((settings.HOST, settings.PORT))
        self.socket.listen(self.MAX_SOCKET_LISTEN)

        self.q 
            
            = queue.Queue(settings.MAX_CONCURRENT_COUNT) 
            
              #
            
            
               可以配置最大并發數
            
            
              def
            
            
               server_accept(self):
        
            
            
              '''
            
            
              等待client連接
            
            
              '''
            
            
              print
            
            (
            
              '
            
            
              starting...
            
            
              '
            
            
              )
        
            
            
              while
            
            
               True:
            self.conn,self.client_addr 
            
            =
            
               self.socket.accept()
            
            
            
              print
            
            (
            
              '
            
            
              客戶端地址:
            
            
              '
            
            
              , self.client_addr)

            
            
            
              #
            
            
              pool.submit(self.get_recv, self.conn)
            
            
              #
            
            
              self.server_accept.close()
            
            
              try
            
            
              :
                
            
            
              #
            
            
               t = Thread(target=self.server_handle, args=(self.conn, )) #報這個錯(TypeError: server_handle() takes 1 positional argument but 2 were given)
            
            
                t = Thread(target=self.server_handle(), args=
            
              (self.conn, ))
                self.q.put(t)
                t.start()
            
            
            
              except
            
            
               Exception as e:
                
            
            
              print
            
            
              (e)
                self.conn.close()
                self.q.get()

    
            
            
              def
            
            
               get_recv(self):
        
            
            
              '''
            
            
              接收client發來的數據
            
            
              '''
            
            
              return
            
            
               pickle.loads(self.conn.recv(self.MAX_RECV_SIZE))

    
            
            
              def
            
            
               auth(self):
        
            
            
              '''
            
            
              處理用戶的認證請求
        1、根據username讀取accounts.ini文件,password相比,判斷用戶是否存在
        2、將程序運行的目錄從bin/ftp_server.py修改到用戶home/alice,方便之后查詢ls
        3、給client返回用戶的詳細信息
        
            
            
              '''
            
            
              while
            
            
               True:
            user_dic 
            
            =
            
               self.get_recv()
            username 
            
            = user_dic.get(
            
              '
            
            
              username
            
            
              '
            
            
              )
            user_handle 
            
            =
            
               UserHandle(username)
            user_data 
            
            =
            
               user_handle.judge_user()
            
            
            
              #
            
            
               判斷用戶是否存在,返回列表
            
            
              #
            
            
               如[('password','202cb962ac59075b964b07152d234b70'),('homedir','home/alex'),('quota','100')]
            
            
              if
            
            
               user_data:
                
            
            
              if
            
             user_data[0][1] == hashlib.md5(user_dic.get(
            
              '
            
            
              password
            
            
              '
            
            ).encode(
            
              '
            
            
              utf-8
            
            
              '
            
            )).hexdigest(): 
            
              #
            
            
               密碼也相同
            
            
                    self.conn.send(struct.pack(
            
              '
            
            
              i
            
            
              '
            
            , 1))  
            
              #
            
            
              登錄成功返回
            
            
                    self.username =
            
               username
                    self.homedir_path 
            
            = 
            
              '
            
            
              %s %s %s
            
            
              '
            
             %(settings.BASE_DIR, 
            
              '
            
            
              home
            
            
              '
            
            
              , self.username)
                    os.chdir(self.homedir_path) 
            
            
              #
            
            
              將程序運行的目錄名修改到用戶home目錄下
            
            
                    self.quota_bytes = int(user_data[2][1]) * 1024 * 1024 
            
              #
            
            
              將用戶配額大小從M改到字節
            
            
                    user_info_dic =
            
               {
                        
            
            
              '
            
            
              username
            
            
              '
            
            
              : username,
                        
            
            
              '
            
            
              homedir
            
            
              '
            
            : user_data[1][1
            
              ],
                        
            
            
              '
            
            
              quota
            
            
              '
            
            : user_data[2][1
            
              ]
                    }
                    self.conn.send(pickle.dumps(user_info_dic))   
            
            
              #
            
            
              用戶的詳細信息發送到客戶端
            
            
              return
            
            
               True
                
            
            
              else
            
            
              :
                    self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            
              , 0))
            
            
            
              else
            
            
              :
                self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            
              , 0))
    
            
            
              def
            
            
               readfile(self):
        
            
            
              '''
            
            
              讀取文件,得到文件內容的bytes型
            
            
              '''
            
            
              
        with open(self.filepath, 
            
            
              '
            
            
              rb
            
            
              '
            
            
              ) as f:
            filedata 
            
            =
            
               f.read()
        
            
            
              return
            
            
               filedata

    
            
            
              def
            
            
               getfile_md5(self):
        
            
            
              '''
            
            
              對文件內容md5
            
            
              '''
            
            
              return
            
            
               hashlib.md5(self.readfile()).hexdigest()
    
            
            
              def
            
            
               get(self):
        
            
            
              '''
            
            
              從server下載文件到client
        
            
            
              '''
            
            
              if
            
             len(self.cmds) > 1
            
              :
            filename 
            
            = self.cmds[1
            
              ]
            filepath 
            
            = os.path.join(os.getcwd(),filename)  
            
              #
            
            
              os.getcwd()得到當前工作目錄
            
            
              if
            
             os.path.isfile(filepath):  
            
              #
            
            
              判斷文件是否存在
            
            
                exist_file_size = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            , self.conn.recv(4
            
              ))[0]
                self.filepath 
            
            =
            
               filepath
                header_dic 
            
            =
            
               {
                    
            
            
              '
            
            
              filename
            
            
              '
            
            
              : filename,
                    
            
            
              '
            
            
              file_md5
            
            
              '
            
            
              : self.getfile_md5(),
                    
            
            
              '
            
            
              file_size
            
            
              '
            
            
              : os.path.getsize(self.filepath)
                }
                header_bytes 
            
            =
            
               pickle.dumps(header_dic)
                
            
            
              if
            
             exist_file_size:  
            
              #
            
            
              表示之前被下載過一部分
            
            
                    self.conn.send(struct.pack(
            
              '
            
            
              i
            
            
              '
            
            
              , len(header_bytes)))
                    self.conn.send(header_bytes)
                    
            
            
              if
            
             exist_file_size !=
            
               os.path.getsize(self.filepath):
                        with open(self.filepath, 
            
            
              '
            
            
              rb
            
            
              '
            
            
              ) as f:
                            f.seek(exist_file_size)
                            
            
            
              for
            
             line 
            
              in
            
            
               f:
                                self.conn.send(line)
                    
            
            
              else
            
            
              :
                        
            
            
              print
            
            (
            
              '
            
            
              斷電和文件本身大小一樣
            
            
              '
            
            
              )
                
            
            
              else
            
            :    
            
              #
            
            
              文件第一次下載
            
            
                    self.conn.send(struct.pack(
            
              '
            
            
              i
            
            
              '
            
            
              , len(header_bytes)))
                    self.conn.send(header_bytes)
                    with open(self.filepath, 
            
            
              '
            
            
              rb
            
            
              '
            
            
              ) as  f:
                        
            
            
              for
            
             line 
            
              in
            
            
               f:
                            self.conn.send(line)
            
            
            
              else
            
            
              :
                
            
            
              print
            
            (
            
              '
            
            
              當前目錄下文件不存在
            
            
              '
            
            
              )
                self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            
              ,0))
        
            
            
              else
            
            
              :
            
            
            
              print
            
            (
            
              '
            
            
              用戶沒用輸入文件名
            
            
              '
            
            
              )
    
            
            
              def
            
            
               recursion_file(self,menu):
        
            
            
              '''
            
            
              遞歸查詢用戶home/alice目錄下的所有文件,算出文件的大小
            
            
              '''
            
            
              
        res 
            
            = os.listdir(menu) 
            
              #
            
            
              指定目錄下所有的文件和目錄名
            
            
              for
            
             i 
            
              in
            
            
               res:
            path 
            
            = 
            
              '
            
            
              %s %s
            
            
              '
            
             %
            
               (menu, i)
            
            
            
              if
            
             os.path.isdir(path): 
            
              #
            
            
              判斷指定對象是否為目錄
            
            
                              self.recursion_file(path)
            
            
            
              elif
            
            
               os.path.isfile(path):
                self.home_bytes_size 
            
            +=
            
               os.path.getsize(path)

    
            
            
              def
            
            
               current_home_size(self):
        
            
            
              '''
            
            
              得到當前用戶home/alice目錄的大小,字節/M
            
            
              '''
            
            
              
        self.home_bytes_size 
            
            =
            
               0
        self.recursion_file(self.homedir_path)
        
            
            
              print
            
            (
            
              '
            
            
              字節:
            
            
              '
            
            , self.home_bytes_size)  
            
              #
            
            
               單位是字節
            
            
        home_m_size = round(self.home_bytes_size / 1024 /1024, 1
            
              )
        
            
            
              print
            
            (
            
              '
            
            
              單位M:
            
            
              '
            
            , home_m_size)  
            
              #
            
            
              單位是: M
            
            
              def
            
            
               put(self):
        
            
            
              '''
            
            
              從client上傳文件到server當前工作目錄下
            
            
              '''
            
            
              if
            
             len(self.cmds) > 1
            
              :
            state_size 
            
            = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            ,self.conn.recv(4
            
              ))[0]
            
            
            
              if
            
            
               state_size:
                self.current_home_size()  
            
            
              #
            
            
              算出了home下已被占用的大小self.home_bytes_size
            
            
                header_bytes = self.conn.recv(struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            , self.conn.recv(4
            
              ))[0])
                header_dic 
            
            =
            
               pickle.loads(header_bytes)
                
            
            
              print
            
            
              (header_dic)
                filename 
            
            = header_dic.get(
            
              '
            
            
              filename
            
            
              '
            
            
              )
                file_size 
            
            = header_dic.get(
            
              '
            
            
              file_size
            
            
              '
            
            
              )
                file_md5 
            
            = header_dic.get(
            
              '
            
            
              file_md5
            
            
              '
            
            
              )

                upload_filepath 
            
            =
            
               os.path.join(os.getcwd(), filename)
                self.filepath 
            
            = upload_filepath  
            
              #
            
            
              為了全局變量讀取文件算md5時方便
            
            
              if
            
             os.path.exists(upload_filepath): 
            
              #
            
            
              文件已經存在
            
            
                    self.conn.send(struct.pack(
            
              '
            
            
              i
            
            
              '
            
            , 1
            
              ))
                    has_size 
            
            =
            
               os.path.getsize(upload_filepath)
                    
            
            
              if
            
             has_size ==
            
               file_size:
                        
            
            
              print
            
            (
            
              '
            
            
              文件已經存在
            
            
              '
            
            
              )
                        self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            
              , 0))
                    
            
            
              else
            
            : 
            
              #
            
            
              上次沒有傳完,接著繼續傳
            
            
                        self.conn.send(struct.pack(
            
              '
            
            
              i
            
            
              '
            
            , 1
            
              ))
                        
            
            
              if
            
             self.home_bytes_size + int(file_size - has_size) >
            
               self.quota_bytes:
                            
            
            
              print
            
            (
            
              '
            
            
              超出了用戶的配額
            
            
              '
            
            
              )
                            self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            
              , 0))
                        
            
            
              else
            
            
              :
                            self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            ,1
            
              ))
                            self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            
              , has_size))
                            with open(upload_filepath, 
            
            
              '
            
            
              ab
            
            
              '
            
            
              ) as f:
                                f.seek(has_size)
                                
            
            
              while
            
             has_size <
            
               file_size:
                                    recv_bytes 
            
            =
            
               self.conn.recv(self.MAX_RECV_SIZE)
                                    f.write(recv_bytes)
                                    has_size 
            
            +=
            
               len(recv_bytes)
                                    self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            , has_size))  
            
              #
            
            
              為了顯示進度條
            
            
              if
            
             self.getfile_md5() == file_md5:  
            
              #
            
            
              判斷下載下來的文件MD5值和server傳過來的MD5值是否一致
            
            
              print
            
            (
            
              '
            
            
              \033[1;32m上傳成功\033[0m
            
            
              '
            
            
              )
                                self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            , 1
            
              ))
                            
            
            
              else
            
            
              :
                                
            
            
              print
            
            (
            
              '
            
            
              \033[1;32m上傳失敗\033[0m
            
            
              '
            
            
              )
                                self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            
              , 0))
                
            
            
              else
            
            : 
            
              #
            
            
              第一次上傳
            
            
                    self.conn.send(struct.pack(
            
              '
            
            
              i
            
            
              '
            
            
              , 0))
                    
            
            
              if
            
             self.home_bytes_size + int(file_size) >
            
               self.quota_bytes:
                        
            
            
              print
            
            (
            
              '
            
            
              \033[1;32m超出了用戶的配額\033[0m
            
            
              '
            
            
              )
                        self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            
              , 0))
                    
            
            
              else
            
            
              :
                        self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            , 1
            
              ))
                        with open(upload_filepath, 
            
            
              '
            
            
              wb
            
            
              '
            
            
              ) as f:
                            recv_size 
            
            =
            
               0
                            
            
            
              while
            
             recv_size <
            
               file_size:
                                file_bytes 
            
            =
            
               self.conn.recv(self.MAX_RECV_SIZE)
                                f.write(file_bytes)
                                recv_size 
            
            +=
            
               len(file_bytes)
                                self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            , recv_size)) 
            
              #
            
            
              為了進度條的顯示
            
            
              if
            
             self.getfile_md5() == file_md5:  
            
              #
            
            
              判斷下載下來的文件MD5值和server傳過來的MD5值是否一致
            
            
              print
            
            (
            
              '
            
            
              \033[1;32m上傳成功\033[0m
            
            
              '
            
            
              )
                            self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            , 1
            
              ))
                        
            
            
              else
            
            
              :
                            
            
            
              print
            
            (
            
              '
            
            
              \033[1;32m上傳失敗\033[0m
            
            
              '
            
            
              )
                            self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            
              , 0))
            
            
            
              else
            
            
              :
                
            
            
              print
            
            (
            
              '
            
            
              待傳的文件不存在
            
            
              '
            
            
              )
        
            
            
              else
            
            
              :
            
            
            
              print
            
            (
            
              '
            
            
              用戶沒有輸入文件名
            
            
              '
            
            
              )

    
            
            
              def
            
            
               ls(self):
        
            
            
              '''
            
            
              查詢當前工作目錄下,先返回文件列表的大小,再返回查詢的結果
            
            
              '''
            
            
              
        subpro_obj 
            
            = subprocess.Popen(
            
              '
            
            
              dir
            
            
              '
            
            , shell=
            
              True,
                                      stdout
            
            =
            
              subprocess.PIPE,
                                      stderr
            
            =
            
              subprocess.PIPE)
        stdout 
            
            =
            
               subpro_obj.stdout.read()
        stderr 
            
            =
            
               subpro_obj.stderr.read()
        self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            , len(stdout +
            
               stderr)))
        self.conn.send(stdout)
        self.conn.send(stderr)

    
            
            
              def
            
            
               mkdir(self):
        
            
            
              '''
            
            
              在當前目錄下,增加目錄
            
            
              '''
            
            
              if
            
             len(self.cmds) > 1
            
              :
            mkdir_path 
            
            = os.path.join(os.getcwd(),self.cmds[1
            
              ])
            
            
            
              if
            
            
              not
            
             os.path.exists(mkdir_path): 
            
              #
            
            
              查看目錄名是否存在
            
            
                              os.mkdir(mkdir_path)
                
            
            
              print
            
            (
            
              '
            
            
              增加目錄成功
            
            
              '
            
            
              )
                self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            , 1)) 
            
              #
            
            
              增加目錄成功,返回1
            
            
              else
            
            
              :
                
            
            
              print
            
            (
            
              '
            
            
              目錄名已存在
            
            
              '
            
            
              )
                self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            , 0))  
            
              #
            
            
              失敗返回0
            
            
              else
            
            
              :
            
            
            
              print
            
            (
            
              '
            
            
              用戶沒有輸入目錄名
            
            
              '
            
            
              )

    
            
            
              def
            
            
               cd(self):
        
            
            
              '''
            
            
              切換目錄
            
            
              '''
            
            
              if
            
             len(self.cmds) > 1
            
              :
            dir_path 
            
            = os.path.join(os.getcwd(), self.cmds[1
            
              ])
            
            
            
              if
            
             os.path.isdir(dir_path) :
            
              #
            
            
              查看是否是目錄名
            
            
                previous_path = os.getcwd() 
            
              #
            
            
              拿到當前工作的目錄
            
            
                os.chdir(dir_path) 
            
              #
            
            
              改變工作目錄到 . . .
            
            
                target_dir =
            
               os.getcwd()
                
            
            
              if
            
             self.homedir_path 
            
              in
            
             target_dir: 
            
              #
            
            
              判斷homedir_path是否在目標目錄
            
            
              print
            
            (
            
              '
            
            
              切換成功
            
            
              '
            
            
              )
                    self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            , 1)) 
            
              #
            
            
              切換成功返回1
            
            
              else
            
            
              :
                    
            
            
              print
            
            (
            
              '
            
            
              切換失敗
            
            
              '
            
            )   
            
              #
            
            
              切換失敗后,返回到之前的目錄下
            
            
                                  os.chdir(previous_path)
                    self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            
              , 0))
            
            
            
              else
            
            
              :
                
            
            
              print
            
            (
            
              '
            
            
              要切換的目錄不在該目錄下
            
            
              '
            
            
              )
                self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            
              , 0))
        
            
            
              else
            
            
              :
            
            
            
              print
            
            (
            
              '
            
            
              沒有傳入切換的目錄名
            
            
              '
            
            
              )

    
            
            
              def
            
            
               remove(self):
        
            
            
              '''
            
            
              刪除指定的文件,或者空文件夾
            
            
              '''
            
            
              if
            
             len(self.cmds) > 1
            
              :
            file_name 
            
            = self.cmds[1
            
              ]
            file_path 
            
            = 
            
              '
            
            
              %s\%s
            
            
              '
            
             %
            
              (os.getcwd(), file_name)
            
            
            
              if
            
            
               os.path.isfile(file_path):
                os.remove(file_path)
                self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            , 1
            
              ))
            
            
            
              elif
            
             os.path.isdir(file_path):  
            
              #
            
            
              刪除空目錄
            
            
              if
            
            
              not
            
            
               len(os.listdir(file_path)):
                    os.removedirs(file_path)
                    
            
            
              print
            
            (
            
              '
            
            
              刪除成功
            
            
              '
            
            
              )
                    self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            , 1
            
              ))
                
            
            
              else
            
            
              :
                    
            
            
              print
            
            (
            
              '
            
            
              文件夾非空,不能刪除
            
            
              '
            
            
              )
                    self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            
              , 0))
            
            
            
              else
            
            
              :
                
            
            
              print
            
            (
            
              '
            
            
              不是文件也不是文件夾
            
            
              '
            
            
              )
                self.conn.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            
              , 0))
        
            
            
              else
            
            
              :
            
            
            
              print
            
            (
            
              '
            
            
              沒有輸入要刪除的文件
            
            
              '
            
            
              )

    
            
            
              def
            
            
               server_handle(self):
        
            
            
              '''
            
            
              處理與用戶的交互指令
            
            
              '''
            
            
              if
            
            
               self.auth():
            
            
            
              print
            
            (
            
              '
            
            
              \033[1;32m用戶登陸成功\033[0m
            
            
              '
            
            
              )
            
            
            
              while
            
            
               True:
                
            
            
              try
            
            :    
            
              #
            
            
              try ...except 適合windows client斷開
            
            
                    user_input = self.conn.recv(self.MAX_RECV_SIZE).decode(
            
              '
            
            
              utf-8
            
            
              '
            
            
              )
                    
            
            
              #
            
            
               if not user_input: continue #這里適合 linux client斷開
            
            
                    self.cmds =
            
               user_input.split()
                    
            
            
              if
            
            
               hasattr(self,self.cmds[0]):
                        getattr(self,self.cmds[0])()
                    
            
            
              else
            
            
              :
                        
            
            
              print
            
            (
            
              '
            
            
              \033[1;31請用戶重復輸入\033[0m
            
            
              '
            
            
              )
                
            
            
              except
            
            
               Exception:
                    
            
            
              break
            
            
              def
            
            
               run(self):
        self.server_accept()

    
            
            
              def
            
            
                close(self):
        self.socket.close()


            
            
              #
            
            
              if __name__ == '__main__':
            
            
              #
            
            
              pool = ThreadPoolExecutor(10)
            
          

user_handle.py

            
              #
            
            
              _*_ coding:utf-8 _*_
            
            
              
#
            
            
               Author:Simon
            
            
              
#
            
            
               Datetime:2019/8/14 10:26
            
            
              
#
            
            
               Software:PyCharm
            
            
              import
            
            
               configparser

            
            
              import
            
            
               hashlib

            
            
              import
            
            
               os


            
            
              from
            
             conf 
            
              import
            
            
               settings


            
            
              class
            
            
               UserHandle():
    
            
            
              def
            
            
              __init__
            
            
              (self,username):
        self.username
            
            =
            
               username
        self.config 
            
            = configparser.ConfigParser() 
            
              #
            
            
              先生成一個對象
            
            
                      self.config.read(settings.ACCOUNTS_FILE)
    @property
    
            
            
              def
            
            
               password(self):
        
            
            
              '''
            
            
              生成用戶的默認密碼 zhurui
            
            
              '''
            
            
              return
            
             hashlib.md5(
            
              '
            
            
              zhurui
            
            
              '
            
            .encode(
            
              '
            
            
              utf-8
            
            
              '
            
            
              )).hexdigest()
    @property

    
            
            
              def
            
            
               quota(self):
        
            
            
              '''
            
            
              生成每個用戶的磁盤配額
            
            
              '''
            
            
              
        quota 
            
            = input(
            
              '
            
            
              請輸入用戶的磁盤配額大小>>>:
            
            
              '
            
            
              ).strip()
        
            
            
              if
            
            
               quota.isdigit():
            
            
            
              return
            
            
               quota
        
            
            
              else
            
            
              :
            exit(
            
            
              '
            
            
              \033[1;31m磁盤配額必須是整數\033[0m
            
            
              '
            
            
              )

    
            
            
              def
            
            
               add_user(self):
        
            
            
              '''
            
            
              創建用戶,存到accounts.ini
            
            
              '''
            
            
              if
            
            
              not
            
            
               self.config.has_section(self.username):
            
            
            
              print
            
            (
            
              '
            
            
              creating username is : 
            
            
              '
            
            
              , self.username)
            self.config.add_section(self.username)
            self.config.set(self.username, 
            
            
              '
            
            
              password
            
            
              '
            
            
              , self.password)
            self.config.set(self.username, 
            
            
              '
            
            
              homedir
            
            
              '
            
            , 
            
              '
            
            
              home/
            
            
              '
            
            +
            
              self.username)
            self.config.set(self.username, 
            
            
              '
            
            
              quota
            
            
              '
            
            
              , self.quota)
            with open(settings.ACCOUNTS_FILE, 
            
            
              '
            
            
              w
            
            
              '
            
            
              ) as f:
                self.config.write(f)
            os.mkdir(os.path.join(settings.BASE_DIR, 
            
            
              '
            
            
              home
            
            
              '
            
            , self.username)) 
            
              #
            
            
              創建用戶的home文件夾
            
            
              print
            
            (
            
              '
            
            
              \033[1;32m創建用戶成功\033[0m
            
            
              '
            
            
              )
        
            
            
              else
            
            
              :
            
            
            
              print
            
            (
            
              '
            
            
              \033[1;32m用戶已存在\033[0m
            
            
              '
            
            
              )


    
            
            
              def
            
            
               judge_user(self):
        
            
            
              '''
            
            
              判斷用戶是否存在
            
            
              '''
            
            
              if
            
            
               self.config.has_section(self.username):
            
            
            
              return
            
            
               self.config.items(self.username)
        
            
            
              else
            
            
              :
            
            
            
              return
            
          

client客戶端

download文件是儲存下載的文件;upload是上傳文件的儲存庫(download里邊可以不放東西,等待下載即可;upload里邊放你準備上傳給服務端的文件)

ftp_client.py

            
              #
            
            
              _*_ coding:utf-8 _*_
            
            
              
#
            
            
               Author:Simon
            
            
              
#
            
            
               Datetime:2019/8/14 11:12
            
            
              
#
            
            
               Software:PyCharm
            
            
              import
            
            
               os

            
            
              import
            
            
               sys

            
            
              import
            
            
               socket

            
            
              import
            
            
               struct

            
            
              import
            
            
               pickle

            
            
              import
            
            
               hashlib


            
            
              class
            
            
               Ftpclient():
    HOST 
            
            = 
            
              '
            
            
              127.0.0.1
            
            
              '
            
            
              #
            
            
              服務器IP
            
            
    PORT = 8080 
            
              #
            
            
              服務端的端口
            
            
    MAX_RECV_SIZE = 8192
            
              
    DOWNLOAD_PATH 
            
            = os.path.join(os.path.dirname(os.path.abspath(
            
              __file__
            
            )), 
            
              '
            
            
              download
            
            
              '
            
            
              )
    UPLOAD_PATH 
            
            = os.path.join(os.path.dirname(os.path.abspath(
            
              __file__
            
            )), 
            
              '
            
            
              upload
            
            
              '
            
            
              )

    
            
            
              def
            
            
              __init__
            
            
              (self):
        self.socket 
            
            =
            
               socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.connect()

    
            
            
              def
            
            
               connect(self):
        
            
            
              '''
            
            
              連接服務端server
            
            
              '''
            
            
              try
            
            
              :
            self.socket.connect((self.HOST, self.PORT))
        
            
            
              except
            
            
               Exception:
            exit(
            
            
              '
            
            
              \033[1;31mserver還未啟動\033[0m
            
            
              '
            
            
              )

    
            
            
              def
            
            
               get_recv(self):
        
            
            
              '''
            
            
              獲取server返回的數據
            
            
              '''
            
            
              return
            
            
               pickle.loads(self.socket.recv(self.MAX_RECV_SIZE))

    
            
            
              def
            
            
               auth(self):
        
            
            
              '''
            
            
              用戶認證
            
            
              '''
            
            
              
        count 
            
            =
            
               0
        
            
            
              while
            
             count < 3
            
              :
            name 
            
            = input(
            
              '
            
            
              請輸入用戶名>>:
            
            
              '
            
            
              ).strip()
            
            
            
              if
            
            
              not
            
             name: 
            
              continue
            
            
              
            password 
            
            = input(
            
              '
            
            
              請輸入密碼>>:
            
            
              '
            
            
              ).strip()
            user_dic 
            
            =
            
               {
                
            
            
              '
            
            
              username
            
            
              '
            
            
              :name,
                
            
            
              '
            
            
              password
            
            
              '
            
            
              :password
            }
            self.socket.send(pickle.dumps(user_dic))   
            
            
              #
            
            
              把用戶名和密碼發送給server
            
            
            res = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            ,self.socket.recv(4
            
              ))[0]
            
            
            
              if
            
             res:   
            
              #
            
            
              接收返回的信息,并判斷
            
            
              print
            
            (
            
              '
            
            
              welcome
            
            
              '
            
            .center(20,
            
              '
            
            
              -
            
            
              '
            
            
              ))
                user_info_dic 
            
            =
            
               self.get_recv()
                self.username 
            
            = user_info_dic.get(
            
              '
            
            
              username
            
            
              '
            
            
              )
                
            
            
              print
            
            
              (user_info_dic)
                
            
            
              return
            
            
               True
            
            
            
              else
            
            
              :
                
            
            
              print
            
            (
            
              '
            
            
              \033[1;31m用戶名或者密碼不對!\033[0m
            
            
              '
            
            
              )
            count 
            
            += 1

    
            
              def
            
            
               readfile(self):
        
            
            
              '''
            
            
              讀取文件,得到的文件內容的bytes型
            
            
              '''
            
            
              
        with open(self.filepath, 
            
            
              '
            
            
              rb
            
            
              '
            
            
              ) as f:
            filedata 
            
            =
            
               f.read()
        
            
            
              return
            
            
               filedata

    
            
            
              def
            
            
               getfile_md5(self):
        
            
            
              '''
            
            
              對文件內容md5
            
            
              '''
            
            
              return
            
            
               hashlib.md5(self.readfile()).hexdigest()

    
            
            
              def
            
            
               progress_bar(self, num, get_size, file_size):
        
            
            
              '''
            
            
              進度條顯示
            
            
              '''
            
            
              
        float_rate 
            
            = get_size /
            
               file_size
        
            
            
              #
            
            
               rate = str(float_rate * 100)[:5]  #  95.85%
            
            
        rate = round(float_rate * 100,2)   
            
              #
            
            
               95.85%
            
            
              if
            
             num == 1: 
            
              #
            
            
              1表示下載
            
            
            sys.stdout.write(
            
              '
            
            
              \r已下載:\033[1;32m{0}%\033[0m
            
            
              '
            
            
              .format(rate))
        
            
            
              elif
            
             num == 2:   
            
              #
            
            
              2 表示上傳
            
            
            sys.stdout.write(
            
              '
            
            
              \r已上傳:\033[1;32m{0}%\033[0m
            
            
              '
            
            
              .format(rate))
        sys.stdout.flush()

    
            
            
              def
            
            
               get(self):
        
            
            
              '''
            
            
              從server下載文件到client
            
            
              '''
            
            
              if
            
             len(self.cmds) > 1
            
              :
            filename 
            
            = self.cmds[1
            
              ]
            self.filepath 
            
            = os.path.join(self.DOWNLOAD_PATH, filename) 
            
              #
            
            
              結合目錄名和文件名
            
            
              if
            
             os.path.isfile(self.filepath): 
            
              #
            
            
              如果文件存在,支持斷點續傳
            
            
                temp_file_size =
            
               os.path.getsize(self.filepath)
                self.socket.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            
              , temp_file_size))
                header_size 
            
            = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            , self.socket.recv(4
            
              ))[0]
                
            
            
              if
            
             header_size:  
            
              #
            
            
              如果存在
            
            
                    header_dic =
            
               pickle.loads(self.socket.recv(header_size))
                    
            
            
              print
            
            
              (header_dic)
                    filename 
            
            = header_dic.get(
            
              '
            
            
              filename
            
            
              '
            
            
              )
                    file_size 
            
            = header_dic.get(
            
              '
            
            
              file_size
            
            
              '
            
            
              )
                    file_md5 
            
            = header_dic.get(
            
              '
            
            
              file_md5
            
            
              '
            
            
              )

                    
            
            
              if
            
             temp_file_size ==
            
               file_size:
                        
            
            
              print
            
            (
            
              '
            
            
              \033[1;32m文件已經存在\033[0m
            
            
              '
            
            
              )
                    
            
            
              else
            
            
              :
                        
            
            
              print
            
            (
            
              '
            
            
              \033[1;33m正在進行斷點續傳....\033[0m
            
            
              '
            
            
              )
                        download_filepath 
            
            =
            
               os.path.join(self.DOWNLOAD_PATH, filename)
                        with open(download_filepath, 
            
            
              '
            
            
              ab
            
            
              '
            
            
              ) as f:
                            f.seek(temp_file_size)
                            get_size 
            
            =
            
               temp_file_size
                            
            
            
              while
            
             get_size <
            
               file_size:
                                file_bytes 
            
            =
            
               self.socket.recv(self.MAX_RECV_SIZE)
                                f.write(file_bytes)
                                get_size 
            
            +=
            
               len(file_bytes)
                                self.progress_bar(
            
            1, get_size, file_size) 
            
              #
            
            
               1表示下載
            
            
              if
            
             self.getfile_md5() == file_md5:  
            
              #
            
            
              判斷下載下來的文件MD5值和server傳過來的MD5值是否一致
            
            
              print
            
            (
            
              '
            
            
              \n\033[1;32m下載成功\033[0m
            
            
              '
            
            
              )
                        
            
            
              else
            
            
              :
                            
            
            
              print
            
            (
            
              '
            
            
              \n\033[1;32m下載文件大小與源文件大小不一致,請重新下載,將會支持斷點續傳033[0m
            
            
              '
            
            
              )
                
            
            
              else
            
            
              :
                    
            
            
              print
            
            (
            
              '
            
            
              \n\033[1;31m該文件,之前被下載了一部分,但是server端的該文件,已被刪除,無法再次下載\033[0m
            
            
              '
            
            
              )
            
            
            
              else
            
            :  
            
              #
            
            
              文件第一次下載
            
            
                self.socket.send(struct.pack(
            
              '
            
            
              i
            
            
              '
            
            , 0))  
            
              #
            
            
               0 表示之前沒有下載過
            
            
                header_size = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            , self.socket.recv(4
            
              ))[0]
                
            
            
              if
            
            
               header_size:
                    header_dic 
            
            =
            
               pickle.loads(self.socket.recv(header_size))
                    
            
            
              print
            
            
              (header_dic)
                    filename 
            
            = header_dic.get(
            
              '
            
            
              filename
            
            
              '
            
            
              )
                    file_size 
            
            = header_dic.get(
            
              '
            
            
              file_size
            
            
              '
            
            
              )
                    file_md5 
            
            = header_dic.get(
            
              '
            
            
              file_md5
            
            
              '
            
            
              )

                    download_filepath 
            
            =
            
               os.path.join(self.DOWNLOAD_PATH, filename)
                    with open(download_filepath, 
            
            
              '
            
            
              wb
            
            
              '
            
            
              ) as f:
                        get_size 
            
            =
            
               0
                        
            
            
              while
            
             get_size <
            
               file_size:
                            file_bytes 
            
            =
            
               self.socket.recv(self.MAX_RECV_SIZE)
                            f.write(file_bytes)
                            get_size 
            
            +=
            
               len(file_bytes)
                            self.progress_bar(
            
            1, get_size, file_size) 
            
              #
            
            
              1表示下載
            
            
              print
            
            (
            
              '
            
            
              總大小:%s已下載:%s
            
            
              '
            
            %
            
               (file_size, get_size))
                    
            
            
              if
            
             self.getfile_md5() == file_md5:  
            
              #
            
            
              判斷下載下來的文件MD5值和server傳過來的MD5值是否一致
            
            
              print
            
            (
            
              '
            
            
              \n\033[1;32m恭喜你,下載成功\033[0m
            
            
              '
            
            
              )
                    
            
            
              else
            
            
              :
                        
            
            
              print
            
            (
            
              '
            
            
              \n\033[1;32m下載失敗,再次下載支持斷點續傳\033[0m
            
            
              '
            
            
              )
                
            
            
              else
            
            
              :
                    
            
            
              print
            
            (
            
              '
            
            
              \n\033[1;32m當前目錄下,文件不存在\033[0m
            
            
              '
            
            
              )
        
            
            
              else
            
            
              :
            
            
            
              print
            
            (
            
              '
            
            
              用戶沒有輸入文件名
            
            
              '
            
            
              )

    
            
            
              def
            
            
               put(self):
        
            
            
              '''
            
            
              往server自己的home/alice目錄下,當前工作的目錄下上傳文件
            
            
              '''
            
            
              if
            
             len(self.cmds) > 1:   
            
              #
            
            
              確保用戶輸入了文件名
            
            
            filename = self.cmds[1
            
              ]
            filepath 
            
            =
            
               os.path.join(self.UPLOAD_PATH, filename)
            
            
            
              if
            
            
               os.path.isfile(filepath):
                self.socket.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            , 1
            
              ))
                self.filepath 
            
            =
            
               filepath
                filesize 
            
            =
            
               os.path.getsize(self.filepath)
                header_dic 
            
            =
            
               {
                    
            
            
              '
            
            
              filename
            
            
              '
            
            
              : filename,
                    
            
            
              '
            
            
              file_md5
            
            
              '
            
            
              : self.getfile_md5(),
                    
            
            
              '
            
            
              file_size
            
            
              '
            
            
              : filesize
                }
                header_bytes 
            
            =
            
               pickle.dumps(header_dic)
                self.socket.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            
              ,len(header_bytes)))
                self.socket.send(header_bytes)

                state 
            
            = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            , self.socket.recv(4
            
              ))[0]
                
            
            
              if
            
             state: 
            
              #
            
            
              已經存在了
            
            
                    has_state = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            , self.socket.recv(4
            
              ))[0]
                    
            
            
              if
            
            
               has_state:
                        quota_state 
            
            = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            ,self.socket.recv(4
            
              ))[0]
                        
            
            
              if
            
            
               quota_state:
                            has_size 
            
            = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            , self.socket.recv(4
            
              ))[0]
                            with open(self.filepath, 
            
            
              '
            
            
              rb
            
            
              '
            
            
              ) as f:
                                f.seek(has_size)
                                
            
            
              for
            
             line 
            
              in
            
            
               f:
                                    self.socket.send(line)
                                    recv_size 
            
            = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            , self.socket.recv(4
            
              ))[0]
                                    self.progress_bar(
            
            2
            
              , recv_size, filesize)
                            success_state 
            
            = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            , self.socket.recv(4
            
              ))[0]
                            
            
            
              '''
            
            
              這里一定要判斷,因為最后一次send(line)之后等待server返回,
                            server返回,最后一次的recv_size==file_size,但client已經跳出了循環,
                            所以在for外面接收的success_state其實時file_size,這種情況只針對大文件
                            
            
            
              '''
            
            
              if
            
             success_state ==
            
               filesize:
                                success_state 
            
            = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            , self.socket.recv(4
            
              ))[0]

                            
            
            
              if
            
            
               success_state:
                                
            
            
              print
            
            (
            
              '
            
            
              \n\033[1;32m恭喜您,上傳成功\033[0m
            
            
              '
            
            
              )
                            
            
            
              else
            
            
              :
                                
            
            
              print
            
            (
            
              '
            
            
              \n\033[1;32m上傳失敗\033[0m
            
            
              '
            
            
              )
                        
            
            
              else
            
            :  
            
              #
            
            
              超出了配額
            
            
              print
            
            (
            
              '
            
            
              \033[1;31m超出了用戶的配額\033[0m
            
            
              '
            
            
              )
                    
            
            
              else
            
            :  
            
              #
            
            
              存在的大小和文件大小一致,不必再傳
            
            
              print
            
            (
            
              '
            
            
              \033[1;31m當前目錄下,文件已經存在\033[0m
            
            
              '
            
            
              )
                
            
            
              else
            
            :  
            
              #
            
            
              第一次傳
            
            
                    quota_state = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            , self.socket.recv(4
            
              ))[0]
                    
            
            
              if
            
            
               quota_state:
                        with open(self.filepath, 
            
            
              '
            
            
              rb
            
            
              '
            
            
              ) as f:
                            send_bytes 
            
            = b
            
              ''
            
            
              for
            
             line 
            
              in
            
            
               f:
                                self.socket.send(line)
                                send_bytes 
            
            +=
            
               line
                                
            
            
              print
            
            (
            
              '
            
            
              總大小:%s 已上傳:%s
            
            
              '
            
             %
            
               (filesize, len(send_bytes)))

                                recv_size 
            
            = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            ,self.socket.recv(4
            
              ))[0]
                                self.progress_bar(
            
            2
            
              , recv_size, filesize)
                        succes_state 
            
            = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            ,self.socket.recv(4
            
              ))[0]

                        
            
            
              if
            
             succes_state ==
            
               filesize:
                            succes_state 
            
            = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            ,self.socket.recv(4
            
              ))[0]
                        
            
            
              if
            
            
               succes_state:
                            
            
            
              print
            
            (
            
              '
            
            
              \n\033[1;32m恭喜您,上傳成功\033[0m
            
            
              '
            
            
              )
                        
            
            
              else
            
            
              :
                            
            
            
              print
            
            (
            
              '
            
            
              \n\033[1;32m上傳失敗\033[0m
            
            
              '
            
            
              )
                    
            
            
              else
            
            :   
            
              #
            
            
              超出了配額
            
            
              print
            
            (
            
              '
            
            
              \033[1;31m超出了用戶的配額\033[0m
            
            
              '
            
            
              )
            
            
            
              else
            
            :  
            
              #
            
            
              文件不存在
            
            
              print
            
            (
            
              '
            
            
              \033[1;31m文件不存在\033[0m
            
            
              '
            
            
              )
                self.socket.send(struct.pack(
            
            
              '
            
            
              i
            
            
              '
            
            
              , 0))
        
            
            
              else
            
            
              :
            
            
            
              print
            
            (
            
              '
            
            
              用戶沒有輸入文件名
            
            
              '
            
            
              )

    
            
            
              def
            
            
               ls(self):
        
            
            
              '''
            
            
              查詢當前工作目錄下,文件列表
            
            
              '''
            
            
              
        dir_size 
            
            = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            , self.socket.recv(4
            
              ))[0]
        recv_size 
            
            =
            
               0
        recv_bytes 
            
            = b
            
              ''
            
            
              while
            
             recv_size <
            
               dir_size:
            temp_bytes 
            
            =
            
               self.socket.recv(self.MAX_RECV_SIZE)
            recv_bytes 
            
            +=
            
               temp_bytes
            recv_size 
            
            +=
            
               len(temp_bytes)
        
            
            
              print
            
            (recv_bytes.decode(
            
              '
            
            
              gbk
            
            
              '
            
            ))  
            
              #
            
            
              gbk適合windows,utf-8適合linux
            
            
              def
            
            
               mkdir(self):
        
            
            
              '''
            
            
              增加目錄
            
            
              '''
            
            
              if
            
             len(self.cmds) > 1
            
              :
            res 
            
            = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            , self.socket.recv(4
            
              ))[0]
            
            
            
              if
            
            
               res:
                
            
            
              print
            
            (
            
              '
            
            
              \033[1;32m在當前目錄下,增加目錄: %s 成功\033[0m
            
            
              '
            
            % self.cmds[1
            
              ])
            
            
            
              else
            
            
              :
                
            
            
              print
            
            (
            
              '
            
            
              \033[1;31m增加目錄失敗\033[0m
            
            
              '
            
            
              )
        
            
            
              else
            
            
              :
            
            
            
              print
            
            (
            
              '
            
            
              沒有輸入要增加的目錄名
            
            
              '
            
            
              )

    
            
            
              def
            
            
               cd(self):
        
            
            
              '''
            
            
              切換目錄
            
            
              '''
            
            
              if
            
             len(self.cmds) > 1
            
              :
            res 
            
            = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            , self.socket.recv(4
            
              ))[0]
            
            
            
              if
            
            
               res:
                
            
            
              print
            
            (
            
              '
            
            
              \033[1;32m切換成功\033[0m
            
            
              '
            
            
              )
            
            
            
              else
            
            
              :
                
            
            
              print
            
            (
            
              '
            
            
              \033[1;32m切換失敗\033[0m
            
            
              '
            
            
              )
        
            
            
              else
            
            
              :
            
            
            
              print
            
            (
            
              '
            
            
              沒有輸入要切換的目錄名
            
            
              '
            
            
              )

    
            
            
              def
            
            
               remove(self):
        
            
            
              '''
            
            
              刪除指定的文件,或者文件夾
            
            
              '''
            
            
              if
            
             len(self.cmds) > 1
            
              :
            res 
            
            = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            , self.socket.recv(4
            
              ))[0]
            
            
            
              if
            
            
               res:
                
            
            
              print
            
            (
            
              '
            
            
              \033[1;32m刪除成功\033[0m
            
            
              '
            
            
              )
            
            
            
              else
            
            
              :
                
            
            
              print
            
            (
            
              '
            
            
              \033[1;31m刪除失敗\033[0m
            
            
              '
            
            
              )
        
            
            
              else
            
            
              :
            
            
            
              print
            
            (
            
              '
            
            
              沒有輸入要刪除的文件
            
            
              '
            
            
              )

    
            
            
              def
            
            
               interactive(self):
        
            
            
              '''
            
            
              與server交互
            
            
              '''
            
            
              if
            
            
               self.auth():
            
            
            
              while
            
            
               True:
                
            
            
              try
            
            
              :
                    user_input 
            
            = input(
            
              '
            
            
              [%s]>>>:
            
            
              '
            
            %
            
              self.username)
                    
            
            
              if
            
            
              not
            
             user_input:
            
              continue
            
            
              
                    self.socket.send(user_input.encode(
            
            
              '
            
            
              utf-8
            
            
              '
            
            
              ))
                    self.cmds 
            
            =
            
               user_input.split()
                    
            
            
              if
            
            
               hasattr(self, self_cmds[0]):
                        getattr(self, self.cmds[0])()
                    
            
            
              else
            
            
              :
                        
            
            
              print
            
            (
            
              '
            
            
              請重新輸入
            
            
              '
            
            
              )
                
            
            
              except
            
             Exception as e: 
            
              #
            
            
              server關閉了
            
            
              print
            
            
              (e)
                    
            
            
              break
            
            
              def
            
            
               close(self):
        self.socket.close()


            
            
              if
            
            
              __name__
            
             == 
            
              '
            
            
              __main__
            
            
              '
            
            
              :
    ftp_client 
            
            =
            
               Ftpclient()
    ftp_client.interactive()
    ftp_client.close()
            
          

?


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 手机看片高清日韩精品 | 精品亚洲无人区一区二区 | 午夜一级大片 | 久热中文字幕在线 | 综合色区| 九九精品视频免费 | 亚洲国产成人在线观看 | 99视频在线观看免费 | 成人网欧美亚洲影视图片 | 日日射天天操 | 欧美毛片aaaaa片久久久久 | 日本草草影院 | 毛片免费永久不卡视频观看 | 亚洲国产品综合人成综合网站 | 黄在线观看网站 | 男女羞羞视频免费观看 | 高清中文字幕免费观在线 | 欧美一区永久视频免费观看 | 久9热精品视频在线观看 | 久热亚洲 | 伊人成人在线视频 | 日韩香蕉网 | 精品播放 | 久久99国产乱子伦精品免费 | 精品免费 | 久久99热精品免费观看k影院 | 久久的爱久久久久的快乐 | 久久久久国产一级毛片高清板 | 亚洲天天网综合自拍图片专区 | 久久久青草 | 久久综合精品视频 | 精品国产91久久久久久久 | 在线视频久 | 色综合合久久天天综合绕视看 | 久青草国产高清在线视频 | 成人在线欧美 | 狠狠色丁香婷婷久久综合不卡 | 99热久久这里只有精品9 | 国产精品乱码一区二区三区 | 欧美高清不卡 | 四虎永久成人免费 |