zhaoke0727 发表于 2018-8-7 13:36:12

python模拟简单ftp

  需求:开发简单的FTP


[*]用户登陆
[*]上传/下载文件
[*]不同用户家目录不同
[*]查看当前目录下文件
[*]充分使用面向对象知识  代码目录结构:

  流程图:

  客户端代码:
  

  
import os,sys
  
import getpass
  
import platform
  
if platform.system() == "Windows":
  
BASE_DIR = "\\".join(os.path.abspath(os.path.dirname(__file__)).split("\\")[:-1])
  
else:
  
BASE_DIR = "/".join(os.path.abspath(os.path.dirname(__file__)).split("/")[:-1])
  
sys.path.insert(0,BASE_DIR)
  
from modules import ssh

  #print(sys.path)
  if name == "main":
  #host = input("请输入服务器端IP:").strip()
  #port = input("请输入端口:").strip()
  username = input("请输入用户名:").strip()
  password = input("请输入密码:").strip()
  #password = getpass.getpass("请输入密码:").strip()
  ssh.SSH("host","port",username,password)
  

服务端代码:  

  import os,sys
  import socket
  import platform
  if platform.system() == "Windows":
  BASE_DIR = "\".join(os.path.abspath(os.path.dirname(file)).split("\")[:-1])
  else:
  BASE_DIR = "/".join(os.path.abspath(os.path.dirname(file)).split("/")[:-1])
  sys.path.insert(0,BASE_DIR)
  from modules import ftp
  #从文件获取用户账号信息
  def get_acount():
  acount_dict = {}
  f = open(BASE_DIR+"\conf\acount.conf")
  for account in f:
  acount_dict] = account.split()
  return acount_dict
  if name == "main":
  server = socket.socket()
  server.bind(("localhost",10620))
  server.listen(5)
  print("准备接受连接.....")
  while True:
  conn, addr = server.accept()
  auth = conn.recv(1024)
  username = auth.decode("utf-8").split()
  password = auth.decode("utf-8").split()
  acount = get_acount()
  if username in acount and password == acount:
  conn.send(b"success")
  if os.path.exists(("C:\Users\%s" %username)):
  home_dir = "C:\Users\%s" %username
  conn.send(home_dir.encode("utf-8"))
  else:
  os.mkdir("C:\Users\%s" %username)
  conn.send(home_dir)
  os.chdir(home_dir)
  conn.send("登录成功!命令帮助请输入h或?".encode("utf-8"))
  help = '''
  put 上传本地文件到ftp服务器。例如:put file.txt
  get 下载ftp服务器文件到本地。例如:get file.txt
  command 执行操作系统命令。例如:diripconfig
  quit|exit|q 退出登录。例如:q
  '''
  while True:
  command = conn.recv(1024).decode("utf-8")
  if command == "?" or command == "h":
  conn.send(help.encode("utf-8"))
  elif command.split() == "get":# or command.split() == "put":#判断用户是否执行ftp命令
  if len(command.split()) != 2:
  conn.send(("%s命令格式为:%s FileName" %(command.split(),command.split())).encode("utf-8"))
  continue
  else:
  Ftp = ftp.FTP(conn,command.split(),command.split())#调用FTP模块传输文件
  Ftp.download()
  elif command.split() == "put":# 判断用户是否执行ftp命令
  f = open(command.split(), "wb")
  fsize = conn.recv(1024).decode("utf-8")
  conn.send(b"ok")
  while True:
  data = conn.recv(102400)
  f.write(data)
  f.flush()
  if os.path.getsize(command.split()) == int(fsize):
  break
  f.close()
  elif command == "q" or command == "quit" or command == "exit":
  conn.send("q".encode("utf-8"))
  conn.close()
  break
  else:
  res = os.popen(command).read()
  if len(res) == 0:#如果是不存在的系统命令,则提醒用户输入错误
  conn.send(("%s:command not found" % command).encode("utf-8"))
  else: #以上条件都不符合后执行此步骤,此块内容为执行系统命令
  conn.sendall(res.encode("utf-8"))
  continue
  else:
  print(2222)
  conn.close()
  continue
  server.close()
  

ssh模块:  

  import os,sys
  import socket
  import platform
  if platform.system() == "Windows":
  BASE_DIR = "\".join(os.path.abspath(os.path.dirname(file)).split("\")[:-1])
  else:
  BASE_DIR = "/".join(os.path.abspath(os.path.dirname(file)).split("/")[:-1])
  sys.path.insert(0,BASE_DIR)
  from modules import ftp
  class SSH(object):
  def init(self,host,port,username,password):
  client = socket.socket()
  self.host = host
  self.port = port
  self.username = username
  self.password = password
  #client.connect((self.host,int(self.port)))
  client.connect(("localhost",10620))
  #登录时将账号发送到服务端进行验证,验证通过后进入循环命令输入
  #client.send((self.username+" "+self.password).encode("utf-8"))
  client.send(("zhaohh" + " " + "123").encode("utf-8"))
  auth_res = client.recv(1024)
  if auth_res.decode("utf-8") == "success":
  home_dir = client.recv(1024)#获取用户登录成功后的家目录
  welcom = client.recv(1024)
  print(welcom.decode("utf-8"))
  while True:
  command = input("[%s]$ "%home_dir.decode("utf-8")).strip()
  if len(command) == 0:continue
  client.send(command.encode("utf-8"))
  if command.split() == "get":
  f = open(command.split(),"wb")
  fsize = client.recv(1024).decode("utf-8")
  client.send(b"ok")
  while True:
  data = client.recv(102400)
  f.write(data)
  f.flush()
  if os.path.getsize(command.split()) == int(fsize):
  break
  f.close()
  elif command.split() == "put":
  if len(command.split()) != 2:
  print("%s命令格式为:%s FileName" % (command.split(), command.split()))
  continue
  else:
  Ftp = ftp.FTP(client, command.split(), command.split())# 调用FTP模块传输文件
  Ftp.upload()
  else:
  res = client.recv(102400)
  if res.decode("utf-8") == "q":
  exit("已退出登录!")
  else:
  print(res.decode())
  else:
  input("账号错误!")
  

ftp模块:  

  import os
  class FTP(object):
  def init(self,conn,command,filename):
  self.command = command
  self.filename = filename
  self.conn = conn
  

#上传文件  
def upload(self):
  print("上传文件:%s" %self.filename)
  f = open(self.filename,"rb")
  data = f.read()
  fsize = os.path.getsize(self.filename)
  self.conn.send(str(fsize).encode("utf-8"))
  self.conn.recv(1024)
  self.conn.sendall(data)
  

  
#下载文件
  
def download(self):
  f = open(self.filename,"rb")
  data = f.read()
  fsize = os.path.getsize(self.filename)
  self.conn.send(str(fsize).encode("utf-8"))
  self.conn.recv(1024)
  self.conn.sendall(data)
  

  
用户账号文件内容格式:
  
zhaohh 123
  
alex 123
页: [1]
查看完整版本: python模拟简单ftp