需求:开发简单的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()[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 123
alex 123
转载于:https://blog.51cto.com/baiying/2055011