最近由于要在嵌入式系统中加入一个ftp功能,于是用python研究起ftp协议来。这个就是两个星期的学习的结果,它实现了一个最小功能的 ftp server。我用这个验证了我对ftp 协议的理解,可惜的是,它最终证实我的嵌入式系统还有些其他的问题,不在ftp协议的范围内,我还得从tcp/ip协议栈里找原因:-(
要使用它你得修改ftproot的设置,我用winxp自带的ftp程序验证没问题。
view plaincopy to clipboardprint?
- #import sys
- import os,glob,time
- import string
- import socket
- ftproot="f://ftp"
- #faitdir="-rw-rw-rw- 1 user group 1024 Jun 12 14:13 aaa.txt/r/n/-rw-rw-rw- 1 user group 1048576 May 12 16:12 bbb.txt/r/n";
- #faitData="1234567890"*102+"12/r/n"
- class FtpServ:
-
-
- def do_user(self):
- print self.cmd[5:]
- if(self.cmd[5:]=='haha/r/n'):
- self.userok=1
- self.connect.send("331 user name ok,need password./r/n")
- else:
- self.connect.send("430 user name error./r/n")
- def do_pass(self):
- print self.cmd[5:]
- if(self.cmd[5:]=='hehe/r/n'):
- if(self.userok==1):
- self.logined=1
- self.connect.send("230 User logged in, proceed./r/n")
- else:
- self.connect.send("530 who are you/r/n")
- else:
- self.connect.send("430 pass word error./r/n")
- def do_mode(self):
- if(self.comd[5]=='S'):
- self.connect.send("200 stream mode is ok/r/n")
- else:
- self.connect.send("500 only stream mode is support/r/n")
-
- def do_pwd(self):
- #show user the directory here
- self.connect.send("257 /"//" is current directory./r/n")
- return
- def do_noop(self):
- self.connect.send("200 ok/r/n")
- return
- def do_type(self):
- print self.cmd[5:6]
- if(string.lower(self.cmd[5:6])=='i'):
- self.connect.send('200 type set to I./r/n')
- elif(string.lower(self.cmd[5:6])=='a'):
- self.connect.send('200 type set to A./r/n')
- else :
- self.connect.send('500 parm error./r/n')
- def do_quit(self):
- self.connect.send("221 Goodbye./r/n")
- def do_feat(self):
- return
- def do_port(self):
- client=string.split(self.cmd[5:],',')
- self.dataClient='.'.join(client[0:4])
- self.dataPort=int(client[4])*256+int(client[5])
- print "clinet ask data connect to ", self.dataClient,":",self.dataPort
- self.connect.send("200 PORT Command successful./r/n")
- return
- def do_pasv(self):
- self.connect.send("500 passive mode not supported./r/n")
- #---------------------------------------------------
- def do_list(self):
- if(self.dataClient!=''):
- self.connect.send("150 Opening data connection./r/n")
- self.datasocket=socket.socket(socket.AF_INET, socket.SOCK_STREAM) #prepare for data trans
- self.datasocket.connect((self.dataClient,self.dataPort))
- filedir=""
- for i in self.fileList.keys() :
- filedir=filedir+self.fileList
- self.datasocket.send(filedir)
- #self.datasocket.send(faitdir)
- self.datasocket.close()
- self.connect.send("226 Transfer complete./r/n")
- print "dir data sended."
- else:
- self.connect.send("503 on port specify/r/n")
- return
- #--------------------------------------------------
- def do_retr(self):
- if self.cmd[5:-2] in self.fileList.keys():
- print "asking for ",self.cmd[5:-2]
- file=open(ftproot+"//"+self.cmd[5:-2],"rb")
- self.connect.send("150 Opening data connection./r/n")
- self.datasocket=socket.socket(socket.AF_INET, socket.SOCK_STREAM) #prepare for data trans
- self.datasocket.connect((self.dataClient,self.dataPort))
- #self.datasocket.send(faitData)
- data=file.read(1024)
-
- while(data!=""):
- self.datasocket.send(data)
- #print data
- data=file.read(1024)
- self.datasocket.close()
- self.connect.send("226 Transfer complete./r/n")
- else:
- self.connect.send("503 no such file/r/n")
- return
- #---------------------------------------------------------------------
- def do_stor(self):
- filename=self.cmd[5:-2]
- newfile=open(filename,'w')
- self.connect.send("150 Opening data connection./r/n")
- self.datasocket=socket.socket(socket.AF_INET, socket.SOCK_STREAM) #prepare for data trans
- self.datasocket.connect((self.dataClient,self.dataPort))
- while(1):
- buf=self.datasocket.recv(1400)
- if(len(buf)!=0):
- newfile.write(buf)
- else:
- self.datasocket.close()
- break
- newfile.close()
- self.connect.send("226 Transfer complete./r/n")
- print filename," received."
- self.getFileList()
- return
- #---------------------------------------------------------------------
- def getFileList(self):
- self.fileList={}
- tempList=glob.glob(ftproot+'//*.*')
- print tempList
- for i in tempList:
- file=glob.glob(i)[0]
- self.fileList[file[7:]]="-rw-rw-rw- 1 user group "+str(os.stat(file)[6])+" "+/
- time.strftime("%m %d %H:%M",time.gmtime(os.stat(file)[8]))+" "+file[7:]+"/r/n"
- print self.fileList
-
- #---------------------------------------------------------------------
- def __init__(self):
- self.commands={
- 'USER':self.do_user,
- 'PASS':self.do_pass,
- 'LIST':self.do_list,
- 'PORT':self.do_port,
- 'RETR':self.do_retr,
- 'STOR':self.do_stor,
- 'XPWD':self.do_pwd,
- 'PWD':self.do_pwd,
- 'PASV':self.do_pasv,
- 'FEAT':self.do_feat,
- 'TYPE':self.do_type,
- 'NOOP':self.do_noop,
- 'MODE':self.do_mode,
- 'QUIT':self.do_quit
-
- }
- self.cmd=""
- self.myHost=''
- self.myPort=21
- self.dataClient=''
- self.dataPort=25
- self.userok=0
- self.logined=0
- self.connect=None
- self.dataconnect=None
- self.fileList=[]
- self.getFileList()
- socket.setdefaulttimeout(50);
- self.sockobj = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.sockobj.bind((self.myHost, self.myPort)) # bind it to server port number
-
-
-
- def loop(self):
- self.sockobj.listen(2) # listen, allow 5 pending connects
- while(1):
- print "starting ftp service"
- self.connect,self.addr=self.sockobj.accept()
- print 'Server connected by',self.addr
- self.connect.send("220 Wellcom to CNC ftp./r/n")
- while(1):
- self.cmd=self.connect.recv(256)
- print 'recv: ',self.cmd
- if not self.cmd:
- break
- else:
- if(self.cmd[0:4] in self.commands.keys()):
- print "handle command ",self.cmd[0:4]
- self.commands[self.cmd[0:4]]()
- if(self.cmd[0:4]=="QUIT"):
- print "client left!"
- break
- else:
- self.connect.send("500 unkonw command./r/n")
- print 'closing connection',self.addr
- self.connect.close()
-
- if __name__ == "__main__":
- #print faitData
- ftpserver=FtpServ()
- ftpserver.loop()
|