Python模拟FTP文件服务器的操作方法
分为服务端和客户端,要求可以有多个客户端同时操作。
客户端可以查看服务器文件库中有什么文件。
客户端可以从文件库中下载文件到本地。
客户端可以上传一个本地文件到文件库。
使用print在客户端打印命令输入提示,引导操作
服务端
#导入相关模块
fromsocketimport*
frommultiprocessingimportProcess
importsignal,os,time
#绑定IP地址
IP="127.0.0.1"
#绑定端口
PORT=8888
ADDR=(IP,PORT)
#绑定服务器的指定目录
DIR="/home/max/ftp"
#处理查看文件请求
defbrowse(c):
#列表方式查看文件
list=os.listdir("%s"%DIR)
#按通信协议格式组织数据
msg="B"+";".join(list)
#发送到客户端
c.send(msg.encode())
#处理客户端下载文件请求
defdownload(c,file):
#判断文件是否存在且是否是文件
iffileinos.listdir(DIR)andos.path.isfile("%s/%s"%(DIR,file)):
#打开文件
f=open("%s/%s"%(DIR,file),"rb")
#发送下载代码,告知客户端进入"D"
c.send(("D%s"%file).encode())
#等待客户端先进入"D"模式下的recv阻塞函数
time.sleep(0.1)
#循环发送文件
whileTrue:
data=f.read(1000)
ifnotdata:
#设置间隔,等待文件传输完整
time.sleep(0.1)
#约定的信息让客户端退出接收循环
c.send(b"finished")
break
c.send(data)
f.close()
#否则按协议格式发送错误代码
else:
c.send(b"Dfileerror")
#处理客户端上传文件请求
defupload(c,file):
#创建文件
f=open("%s/%s"%(DIR,file),"wb")
#循环接收文件
whileTrue:
data=c.recv(1024)
#收到约定的信息退出循环
ifdata==b"finished":
break
f.write(data)
f.close()
#处理客户端退出请求
deflogin_out(c):
#按协议格式组织信息
msg="Oclosed"
#发给客户端的recv_msg进程
c.send(msg.encode())
defdeal(c):
#发送代码告知客户端连接成功
c.send(b"K")
whileTrue:
#循环接收客户端请求,约定通信协议为"*******"格式
msg=c.recv(1024)
#如果客户端崩了,解除该子进程
ifnotmsg:
break
#解析请求
req=msg.decode().split("",2)
#处理查看文件请求,跳入browse函数
ifreq[0]=="B":
browse(c)
#处理客户端下载文件请求,跳入download函数
elifreq[0]=="D":
download(c,req[1])
#处理客户端上传文件请求,跳入upload函数
elifreq[0]=="U":
upload(c,req[1])
#处理客户端退出请求,跳入login_out函数
elifreq[0]=="O":
login_out(c)
#跳出循环,结束子进程
break
#主程序,父进程用于接收客户端请求并循环创建子进程,子程序处理请求
defmain():
#创建tcp套接字
s=socket()
#绑定服务器地址
s.bind(ADDR)
#设置监听套接字
s.listen()
#处理僵尸进程
signal.signal(signal.SIGCHLD,signal.SIG_IGN)
whileTrue:
#连接客户端
c,addr=s.accept()
#创建子进程,用以处理客户端请求,跳入deal函数
p=Process(target=deal,args=(c,))
#子程序开始执行
p.start()
if__name__=='__main__':
main()
客户端
#导入相关模块
fromsocketimport*
importos,sys,time
#绑定服务端IP地址
IP="127.0.0.1"
#绑定服务端端口
PORT=8888
ADDR=(IP,PORT)
#收到约定的信息退出循环
#发送消息进程
defsend_msg(s):
#等待接收进程先运行到"K"分支
time.sleep(0.1)
whileTrue:
try:
#输入指令
data=input(">>>")
except:
#客户端错误,向服务端发送O
data="O"
ifdata=="B":#查看目录
msg="B"
s.send(msg.encode())
elifdata=="D":#下载文件
#输入想要下载的文件
want=input("download?file:")
msg="D%s"%want
s.send(msg.encode())
elifdata=="U":#上传文件
file=input("upload?file:")
#判断文件是否在客户端文件所在的目录且是文件
iffileinos.listdir(os.getcwd())andos.path.isfile("%s/%s"%(os.getcwd(),file)):
msg="U%s"%file
s.send(msg.encode())
f=open("%s"%file,"rb")
#等待服务端进入upload的recv阻塞函数
time.sleep(0.1)
whileTrue:
data=f.read(1000)
ifnotdata:
#设置间隔,等待文件传输完整
time.sleep(0.1)
#约定的信息让客户端退出接收循环
s.send(b"finished")
break
s.send(data)
f.close()
print("uploadsuccussfully")
#否则按协议格式显示错误代码
else:
print("filenotexist\ninputBDUOtoforward\n",end="")
elifdata=="O":#断开连接
msg="O"
s.send(msg.encode())
sys.exit()
#指令错误
else:
print("inputerror")
#接收消息进程
defrecv_msg(s):
whileTrue:
data=s.recv(1024)
#解析数据
msg=data.decode().split("",2)
ifmsg[0]=="K":#登录成功反馈
print(
"logininsuccessfully\ninputBtobrowse,Dtodownload,Utoupload,Otologinout")
elifmsg[0]=="B":#查看目录反馈
#如果文件库不为空
ifmsg[2]:
print("files:",msg[2],"\n>>>",end="")
else:
print("files:nofiles","\n>>>",end="")
elifmsg[0]=="D":
#服务端文件不存在
ifmsg[1]=="fileerror":
print("filenotexist\ninputBDUOtoforward\n>>>",end="")
continue
#服务端文件存在
else:
f=open("%s"%msg[1],"wb")
whileTrue:
data=s.recv(1024)
#收到约定的信息退出循环
ifdata==b"finished":
break
f.write(data)
f.close()
print("downloadsuccessfully\n>>>",end="")
elifmsg[0]=="O":#收到来自发送消息进程发送到服务端的断开请求
#进程退出并打印提示
sys.exit("loginoutsuccessfully")
#主程序
defmain():
#创建tcp套接字
s=socket()
#连接服务端
s.connect(ADDR)
#创建多进程,子进程用于发送消息,父进程用于接收消息
pid=os.fork()
ifpid<0:
print("systemerror")
#子进程
elifpid==0:
send_msg(s)
#父进程
else:
recv_msg(s)
if__name__=='__main__':
main()
总结
以上所述是小编给大家介绍的Python_模拟FTP文件服务器的操作方法,希望对大家有所帮助,也非常感谢大家对毛票票网站的支持!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。