继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

python模拟简单ftp

慕工程3455409
关注TA
已关注
手记 318
粉丝 78
获赞 293

需求:开发简单的FTP

  1. 用户登陆

  2. 上传/下载文件

  3. 不同用户家目录不同

  4. 查看当前目录下文件

    充分使用面向对象知识
    代码目录结构:
    https://img4.mukewang.com/5b235d070001291e02250314.jpg
    流程图:
    https://img3.mukewang.com/5b235d2600018cf906170699.jpg
    客户端代码:

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()[0]] = account.split()[1]
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()[0]
password = auth.decode("utf-8").split()[1]
acount = get_acount()
if username in acount and password == acount[username]:
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 [file_name]  上传本地文件到ftp服务器。例如:put file.txt
get [file_name]  下载ftp服务器文件到本地。例如:get file.txt
command 执行操作系统命令。例如:dir  ipconfig
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()[0] == "get":# or command.split()[0] == "put":  #判断用户是否执行ftp命令
if len(command.split()) != 2:
conn.send(("%s命令格式为:%s FileName" %(command.split()[0],command.split()[0])).encode("utf-8"))
continue
else:
Ftp = ftp.FTP(conn,command.split()[0],command.split()[1])  #调用FTP模块传输文件
Ftp.download()
elif command.split()[0] == "put":  # 判断用户是否执行ftp命令
f = open(command.split()[1], "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()[1]) == 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()[0] == "get":
f = open(command.split()[1],"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()[1]) == int(fsize):
break
f.close()
elif command.split()[0] == "put":
if len(command.split()) != 2:
print("%s命令格式为:%s FileName" % (command.split()[0], command.split()[0]))
continue
else:
Ftp = ftp.FTP(client, command.split()[0], command.split()[1])  # 调用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 123alex 123

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP