发表于 2015-5-28 11:44:35

[转] python实现最小功能的 ftp server

  最近由于要在嵌入式系统中加入一个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
[*]      if(self.cmd=='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
[*]      if(self.cmd=='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=='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
[*]      if(string.lower(self.cmd)=='i'):
[*]            self.connect.send('200 type set to I./r/n')
[*]      elif(string.lower(self.cmd)=='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,',')
[*]      self.dataClient='.'.join(client)
[*]      self.dataPort=int(client)*256+int(client)
[*]      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 in self.fileList.keys():
[*]            print "asking for ",self.cmd
[*]            file=open(ftproot+"//"+self.cmd,"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
[*]      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)
[*]            self.fileList]="-rw-rw-rw- 1 user group "+str(os.stat(file))+" "+/
[*]                time.strftime("%m %d %H:%M",time.gmtime(os.stat(file)))+" "+file+"/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 in self.commands.keys()):
[*]                        print "handle command ",self.cmd
[*]                        self.commands]()
[*]                        if(self.cmd=="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()
页: [1]
查看完整版本: [转] python实现最小功能的 ftp server