• 需求

1. 用户登陆  ---configparse 存储信息 进行登录验证
2. 上传/下载文件        ---get、put函数
3. 不同用户家目录不同    ----configparse定义家目录
4. 查看当前目录下文件    ----dir命令,如何进行权限判定,只能进入到自己的目录下面?
5. 充分使用面向对象知识    -----就是用类、函数

 

  • 代码结构

python实现简单FTP

  • 服务端

  1 #!/usr/bin/env python
  2 #-*- coding:utf-8 -*-
  3 # @Time    : 2017/12/14 15:25
  4 # @Author  : lichuan
  5 # @File    : 服务端.py
  6 
  7 
  8 import socketserver
  9 import struct
 10 import json
 11 import subprocess
 12 import os
 13 import configparser
 14 from module import common
 15 import subprocess
 16 
 17 class My_FtpServer(socketserver.BaseRequestHandler):
 18 
 19     def handle(self):
 20         # while True:
 21         try:
 22             name = self.name_check()    #进行用户名验证
 23             self.path = common.get_home_path(name)   #根据用户名获取家目录
 24             if not os.path.exists(self.path):
 25                 os.mkdir(self.path)
 26             # os.chdir(path)
 27             print(os.getcwd())
 28             while True:
 29                 data=self.request.recv(8)   #接收命令长度
 30                 if not data:break   #防止在linux、mac等系统中会有问题
 31                 msg_length=struct.unpack('q',data)[0]  #是一个元组形势的数据,包含命令长度
 32                 cmd = self.request.recv(msg_length).decode('utf-8')
 33                 if cmd.upper() == 'QUIT':  #quit 进行退出
 34                     print('break')
 35                     break
 36                 if hasattr(self,cmd.split()[0]): #收到的消息,进行切分,拿出第一个进行判断
 37                     print(cmd.split()[0])
 38                     func = getattr(self,cmd.split()[0])
 39                     func(cmd)
 40                 else:  #如果没有函数,则进行执行命令
 41                     os.chdir(self.path)
 42                     res=subprocess.Popen(cmd,
 43                                      shell=True,
 44                                      stdout=subprocess.PIPE,
 45                                      stderr=subprocess.PIPE)
 46                     err = res.stderr.read()
 47                     if err:
 48                         back_msg=err
 49                     else:
 50                         back_msg=res.stdout.read()
 51                         if cmd.split()[0] == 'cd':
 52                             new_path = os.getcwd()+os.sep+cmd.split()[1]
 53                             if self.path in new_path:
 54                                 print('self.path',self.path)
 55                                 print('new_path',new_path)
 56                                 self.path = new_path
 57                     print(self.path)
 58                     self.send_msg(back_msg)
 59         except Exception as e:
 60             print("Error:",e)
 61             print('handle exception!')
 62 
 63     def send_header(self,file_info): #发送报头
 64         # file_info = {'cmd': cmd,'status': status}
 65         f_head = json.dumps(file_info)  #json化代码,用于传输
 66         f_head_bytes = bytes(f_head, encoding='utf-8') #变成bytes类型
 67         self.request.send(struct.pack('q', len(f_head_bytes)))  # 传报头长度过去
 68         self.request.sendall(f_head_bytes)  # 传报头过去
 69 
 70     def get(self,cmd):
 71         print('----get function----')
 72         # print(os.getcwd())
 73         os.chdir(self.path)
 74         l = cmd.split()
 75         if len(l) != 2:
 76             print('get command is worng!')
 77             return
 78         # BASE_DIR = os.path.dirname(os.path.abspath(__file__))
 79         f = l[1]
 80         if os.path.exists(f):
 81             file_path = os.path.abspath(f)
 82         else:
 83             print('file not exists!')
 84             return
 85         print('file path:',os.path.abspath(file_path))
 86         if os.path.isfile(file_path) and self.path in file_path:
 87             file_size = os.path.getsize(file_path)
 88             file_md5 = common.GetFileMd5(file_path)  # 获取文件的md5值
 89             status = 'OK'
 90             file_info = {'cmd': cmd, 'filename': os.path.basename(file_path), 'file_size': file_size, 'md5': file_md5,'status':status}
 91             # f_head = json.dumps(file_info)
 92             # print(type(f_head))
 93             # f_head_bytes = bytes(f_head, encoding='utf-8')
 94             # print(f_head_bytes,type(f_head_bytes),type(f_head))
 95             # print('len:',len(f_head))
 96             # self.request.send(struct.pack('q', len(f_head_bytes)))  # 传报头长度过去
 97             # self.request.sendall(f_head_bytes)  # 传报头过去
 98             self.send_header(file_info)
 99             with open(file_path, 'rb') as read_f:
100                 for line in read_f:
101                     self.request.send(line)  # 传文件过去
102         else:
103             print('权限不够或者不是文件')
104             status = 'ERROR'
105             file_info = {'cmd': cmd,'status': status}
106             self.send_header(file_info)
107 
108 
109     def put(self,cmd):
110         print('----put function----')
111         os.chdir(self.path)
112         l = cmd.split()
113         if len(l) != 2:
114             print('put command is worng!')
115             return
116         head_l=self.request.recv(8) #接收报头长度
117         longth = int(struct.unpack('q',head_l)[0]) #接收到的应该是个元组,取第一位,即长度
118         file_json = self.request.recv(longth).decode('utf-8')
119         head_dic = json.loads(file_json)
120         status = head_dic['status']
121         if status == 'OK':
122             file_name=head_dic['filename']
123             file_size=head_dic['file_size']
124             recv_size = 0
125             with open(file_name,'wb') as write_f:
126                 while recv_size < file_size:
127                     res=self.request.recv(1024)
128                     recv_size+=len(res)
129                     write_f.write(res)
130                     print(recv_size,file_size)
131             file_path=os.path.abspath(file_name)
132             # print('file_name:',file_name)
133             print('file_path:',file_path)
134             file_md5=common.GetFileMd5(file_path)
135             # print(file_md5)
136             # print(head_dic['md5'])
137             if file_md5 == head_dic['md5']:
138                 print('文件传输成功')
139             else:
140                 print('文件不一致')
141                 os.remove(file_path)
142 
143     def send_msg(self,msg):#用于发送信息
144         self.head_l = struct.pack('q',len(msg))
145         self.request.send(self.head_l)
146         self.request.sendall(msg)
147 
148     #进行用户名密码验证的函数
149     def name_check(self):
150         while True:
151             name = self.request.recv(1024).decode('utf-8')
152             self.request.send('0'.encode('utf-8'))
153             passwd=self.request.recv(1024).decode('utf-8')
154             if common.login(name,passwd):
155                 self.request.send('0'.encode('utf-8'))
156                 return name
157             else:
158                 self.request.send('1'.encode('utf-8'))
159                 continue
160 
161     #执行dir命令显示目录下的内容
162     def show_path_content(self,path):
163         print('show path'+path)
164         cmd = 'dir ' + path
165         res1 = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
166         return res1.stdout.read().decode('gbk')
167 
168 if __name__ == '__main__':
169     fserver = socketserver.ThreadingTCPServer(('127.0.0.1',8001),My_FtpServer)
170     fserver.serve_forever()
171     fserver.server_close()
172     # for l in os.listdir(os.getcwd()):
173     #     print(l)
174     # for i in os.walk(os.path.dirname(os.path.dirname((os.path.abspath(__file__))))):
175     #     print(i)
服务端.py

相关文章: