python--FTP的实现(用socket)

1、要求

作业:开发一个支持多用户在线的FTP程序
要求:
用户加密认证
允许同时多用户登录
每个用户有自己的家目录 ,且只能访问自己的家目录
对用户进行磁盘配额,每个用户的可用空间不同
允许用户在ftp server上随意切换目录
允许用户查看当前目录下文件
允许上传和下载文件,保证文件一致性
文件传输过程中显示进度条
附加功能:支持文件的断点续传

2、目录结构

userinfo里放的是ftp的用户名和密码
homedir是用来放各个用户的家目录,下面的子文件就是对应用户的家目录
代码放在code里,一个client,一个server,那个文件1是测试上传下载时用的测试文件

3、思路
(1)对于用户加密认证
就是读取userinfo中的用户名和密码,对比用户输入的信息,对的上,就可以继续其他操作,否则就不行
(2)client和server的交互
用socket实现
在client端,先建立socket对象,再connect,再send客户的信息,等待server回复,即client.recv
在server端,先建立socket对象,再bind主机和端口,设置listen,等待相应的client地址发来消息,accept它,并做出相应的反应,发回去
(3)目录的切换
用到os模块中的os.path.dirname os.getcwd os.path.join os.chdir等方法来获取当前路径、父目录、组合路径、变更路径
(4)具体代码

client如下:
 1 import socket
 2 import os
 3 
 4 fddir=os.path.dirname(os.path.dirname(__file__))#project根目录
 5 
 6 #建立socket,连接本地21端口
 7 client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 8 client.connect(('127.0.0.1',21))
 9 
10 #登录验证
11 name=input("ftp登录用户名:")
12 password=input("登陆密码:")
13 loginstring='loginstring '+name+' '+password
14 client.send(loginstring.encode('utf-8'))
15 reply=client.recv(1024).decode('utf-8')
16 print(reply)
17 
18 #登录成功才能有连续的ftp请求输入
19 def showdir():
20     msg='currentdir'
21     return msg
22 def showfiles():
23     msg='currentfiles'
24     return msg
25 def downdir():
26     msg='downdir '
27     msg += input('请输入你要进入的目录名字:')
28     return msg
29 def updir():
30     msg='updir'
31     return msg
32 def download():
33     msg = 'download '
34     filename=input('输入你要下载的文件名(保存到当前路径)')
35     msg +=filename
36     return msg
37 def upload():
38     msg='upload '
39     filedir=input("输入你要上传的文件路径")
40     filename=filedir.split('\\')[-1]
41     msg += filename+' '
42     with open(filedir,'r') as fd:
43         msg +=fd.read()
44     return msg
45 def bye():
46     msg='exit'
47     return msg
48 
49 ftprequest={'1':showdir,'2':showfiles,'3':downdir,'4':updir,'5':download,'6':upload,'7':bye}
50 if reply=='login success...':
51     ftphome = '%s\homedir\%s'%(fddir,name)
52     while True:
53         incmd = input("你要干嘛?\n"
54                       "1、显示当前路径\n2、显示当前文件列表\n3、进入文件夹\n4、返回上一层\n"
55                       "5、下载文件\n6、上传文件\n7、退出")
56         if incmd in ftprequest.keys():
57             mess=ftprequest[incmd]()
58             client.send(mess.encode('utf-8'))
59             if incmd=='7':
60                 break
61             reply=client.recv(102400).decode('utf-8')
62             if incmd=='5':
63                 filename=input("请输入要保存的名字:")
64                 filepath=os.path.join(os.getcwd(),filename)
65                 with open(filepath,'w') as fd:
66                     fd.write(reply)
67             print(reply)
68 client.close()
server端:
 1 import socket
 2 import os
 3 
 4 #从文件获取用户名密码,放在字典里
 5 userinfo={}
 6 fddir=os.path.dirname(os.path.dirname(__file__))#project根目录
 7 homedir=fddir+'\homedir'
 8 
 9 with open(r'%s\userinfo\userinfo'%fddir,'r',encoding='utf-8') as userfd:
10     line=userfd.readline()
11     while line:
12         name=line.split()[0]
13         passwd=line.split()[1]
14         userinfo[name]=passwd
15         line=userfd.readline()
16 #建立服务器socket、绑定、监听
17 server=socket.socket()
18 server.bind(('127.0.0.1',21))
19 server.listen(5)
20 #等待接收数据
21 while True:
22     print("server waiting...")
23     conn,addr=server.accept()
24 
25     while True:
26         clientdata=conn.recv(1024) #1M data
27         clientdatastr=clientdata.decode('utf-8')
28         '''
29         分辨传进来的是什么命令做相应的处理
30         1、登录命令以loginstring开头--验证用户名密码是否正确
31         2、退出是exit或quit--关闭conn,退出接受命令的状态
32         3、其他
33         '''
34         if clientdatastr.startswith('loginstring'):
35             strlist=clientdatastr.split()
36             namein=strlist[1]
37             passin=strlist[2]
38             if namein in userinfo.keys() and userinfo[namein]==passin:
39                 os.chdir('%s\homedir\%s' % (fddir, namein))
40                 conn.send(b'login success...')
41             else:
42                 conn.send(b'user name and password wrong......')
43                 conn.close()
44                 break
45         elif clientdatastr=='exit' or clientdatastr=='quit':
46             conn.close()
47             break
48         elif clientdatastr=='currentdir':
49             curdir=os.getcwd()
50             conn.send(curdir.encode('utf-8'))
51         elif clientdatastr=='currentfiles':
52             curdir=os.getcwd()
53             returnstr=''
54             for root,dirs,files in os.walk(curdir):
55                 returnstr+='rootdir:'+root+'\n'
56                 for d in dirs:
57                     returnstr +='directory:'+d+'\n'
58                 for f in files:
59                     returnstr +='file:'+f+'\n'
60             print(returnstr)
61             conn.send(returnstr.encode('utf-8'))
62         elif clientdatastr.startswith('downdir'):
63             strlist=clientdatastr.split()
64             dirname=strlist[1]
65             targetdir=os.getcwd()+'\\'+dirname
66             os.chdir(targetdir)
67             curdir=os.getcwd()
68             conn.send(curdir.encode('utf-8'))
69         elif clientdatastr=='updir':
70             fatherdir=os.path.dirname(os.getcwd())
71             os.chdir(fatherdir)
72             curdir=os.getcwd()
73             conn.send(curdir.encode('utf-8'))
74         elif clientdatastr.startswith('download'):
75             strlist=clientdatastr.split()
76             filename=strlist[1]
77             dirname=os.path.join(os.getcwd(),filename)
78             with open(dirname,'r') as fd:
79                 msg=fd.read()
80             conn.send(msg)
81         elif clientdatastr.startswith('upload'):
82             strlist=clientdatastr.split()
83             filename=strlist[1]
84             filecont=strlist[2]
85             dir=os.path.join(os.getcwd(),filename)
86             with open(filename,'w') as fd:
87                 fd.write(filecont)
88             conn.send('***')
89         else:
90             cmdstr = clientdatastr.strip()
91             print(cmdstr)
92             result=os.popen(cmdstr)
93             print(result.read())
94             conn.send(result.read().encode('utf-8'))

 


 





posted @ 2017-11-15 15:15  susenyan  阅读(639)  评论(0编辑  收藏  举报