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

最近由于要在嵌入式系统中加入一个ftp功能,于是用python研究起ftp协议来。这个就是两个星期的学习的结果,它实现了一个最小功能的 ftp server。我用这个验证了我对ftp 协议的理解,可惜的是,它最终证实我的嵌入式系统还有些其他的问题,不在ftp协议的范围内,我还得从tcp/ip协议栈里找原因:-(
    要使用它你得修改ftproot的设置,我用winxp自带的ftp程序验证没问题。

  1. #import sys   
  2. import os,glob,time  
  3. import string  
  4. import socket  
  5. ftproot="f://ftp"  
  6. #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";   
  7. #faitData="1234567890"*102+"12/r/n"   
  8. class FtpServ:  
  9.      
  10.           
  11.     def do_user(self):  
  12.         print self.cmd[5:]  
  13.         if(self.cmd[5:]=='haha/r/n'):  
  14.             self.userok=1  
  15.             self.connect.send("331 user name ok,need password./r/n")  
  16.         else:  
  17.             self.connect.send("430 user name error./r/n")  
  18.     def do_pass(self):  
  19.         print self.cmd[5:]  
  20.         if(self.cmd[5:]=='hehe/r/n'):  
  21.             if(self.userok==1):  
  22.                 self.logined=1  
  23.                 self.connect.send("230 User logged in, proceed./r/n")  
  24.             else:  
  25.                 self.connect.send("530 who are you/r/n")  
  26.         else:  
  27.             self.connect.send("430 pass word error./r/n")  
  28.     def do_mode(self):  
  29.         if(self.comd[5]=='S'):  
  30.             self.connect.send("200 stream mode is ok/r/n")  
  31.         else:  
  32.             self.connect.send("500 only stream mode is support/r/n")  
  33.                  
  34.     def do_pwd(self):  
  35.         #show user the directory here   
  36.         self.connect.send("257 /"//" is current directory./r/n")  
  37.         return  
  38.     def do_noop(self):  
  39.         self.connect.send("200 ok/r/n")  
  40.         return  
  41.     def do_type(self):  
  42.         print self.cmd[5:6]  
  43.         if(string.lower(self.cmd[5:6])=='i'):  
  44.             self.connect.send('200 type set to I./r/n')  
  45.         elif(string.lower(self.cmd[5:6])=='a'):  
  46.             self.connect.send('200 type set to A./r/n')  
  47.         else :  
  48.             self.connect.send('500 parm error./r/n')  
  49.     def do_quit(self):  
  50.         self.connect.send("221 Goodbye./r/n")  
  51.     def do_feat(self):  
  52.         return  
  53.     def do_port(self):  
  54.         client=string.split(self.cmd[5:],',')  
  55.         self.dataClient='.'.join(client[0:4])  
  56.         self.dataPort=int(client[4])*256+int(client[5])  
  57.         print "clinet ask data connect to "self.dataClient,":",self.dataPort  
  58.         self.connect.send("200 PORT Command successful./r/n")  
  59.         return  
  60.     def do_pasv(self):  
  61.         self.connect.send("500 passive mode not supported./r/n")  
  62. #---------------------------------------------------   
  63.     def do_list(self):  
  64.         if(self.dataClient!=''):  
  65.             self.connect.send("150 Opening data connection./r/n")  
  66.             self.datasocket=socket.socket(socket.AF_INET, socket.SOCK_STREAM) #prepare for data trans   
  67.             self.datasocket.connect((self.dataClient,self.dataPort))  
  68.             filedir=""  
  69.             for i in self.fileList.keys() :  
  70.                 filedir=filedir+self.fileList  
  71.             self.datasocket.send(filedir)  
  72.             #self.datasocket.send(faitdir)   
  73.             self.datasocket.close()  
  74.             self.connect.send("226 Transfer complete./r/n")  
  75.             print "dir data sended."  
  76.         else:  
  77.             self.connect.send("503 on port specify/r/n")  
  78.         return  
  79. #--------------------------------------------------   
  80.     def do_retr(self):  
  81.         if self.cmd[5:-2in self.fileList.keys():  
  82.             print "asking for ",self.cmd[5:-2]  
  83.             file=open(ftproot+"//"+self.cmd[5:-2],"rb")  
  84.             self.connect.send("150 Opening data connection./r/n")  
  85.             self.datasocket=socket.socket(socket.AF_INET, socket.SOCK_STREAM) #prepare for data trans   
  86.             self.datasocket.connect((self.dataClient,self.dataPort))  
  87.             #self.datasocket.send(faitData)   
  88.             data=file.read(1024)  
  89.               
  90.             while(data!=""):  
  91.                 self.datasocket.send(data)  
  92.                 #print data   
  93.                 data=file.read(1024)  
  94.             self.datasocket.close()  
  95.             self.connect.send("226 Transfer complete./r/n")  
  96.         else:  
  97.             self.connect.send("503 no such file/r/n")  
  98.         return  
  99. #---------------------------------------------------------------------   
  100.     def do_stor(self):  
  101.         filename=self.cmd[5:-2]  
  102.         newfile=open(filename,'w')  
  103.         self.connect.send("150 Opening data connection./r/n")  
  104.         self.datasocket=socket.socket(socket.AF_INET, socket.SOCK_STREAM) #prepare for data trans   
  105.         self.datasocket.connect((self.dataClient,self.dataPort))  
  106.         while(1):  
  107.             buf=self.datasocket.recv(1400)  
  108.             if(len(buf)!=0):  
  109.                 newfile.write(buf)  
  110.             else:  
  111.                 self.datasocket.close()  
  112.                 break  
  113.         newfile.close()  
  114.         self.connect.send("226 Transfer complete./r/n")  
  115.         print filename," received."  
  116.         self.getFileList()  
  117.         return  
  118. #---------------------------------------------------------------------   
  119.     def getFileList(self):  
  120.         self.fileList={}  
  121.         tempList=glob.glob(ftproot+'//*.*')  
  122.         print tempList  
  123.         for i in tempList:  
  124.             file=glob.glob(i)[0]  
  125.             self.fileList[file[7:]]="-rw-rw-rw- 1 user group "+str(os.stat(file)[6])+" "+/  
  126.                 time.strftime("%m %d %H:%M",time.gmtime(os.stat(file)[8]))+" "+file[7:]+"/r/n"  
  127.         print self.fileList  
  128.           
  129. #---------------------------------------------------------------------   
  130.     def __init__(self):  
  131.         self.commands={  
  132.               'USER':self.do_user,  
  133.               'PASS':self.do_pass,  
  134.               'LIST':self.do_list,  
  135.               'PORT':self.do_port,  
  136.               'RETR':self.do_retr,  
  137.               'STOR':self.do_stor,  
  138.               'XPWD':self.do_pwd,  
  139.               'PWD':self.do_pwd,  
  140.               'PASV':self.do_pasv,  
  141.               'FEAT':self.do_feat,  
  142.               'TYPE':self.do_type,  
  143.               'NOOP':self.do_noop,  
  144.               'MODE':self.do_mode,  
  145.               'QUIT':self.do_quit  
  146.                 
  147.               }  
  148.         self.cmd=""  
  149.         self.myHost=''  
  150.         self.myPort=21  
  151.         self.dataClient=''  
  152.         self.dataPort=25  
  153.         self.userok=0  
  154.         self.logined=0  
  155.         self.connect=None  
  156.         self.dataconnect=None  
  157.         self.fileList=[]  
  158.         self.getFileList()  
  159.         socket.setdefaulttimeout(50);  
  160.         self.sockobj = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
  161.         self.sockobj.bind((self.myHost, self.myPort)) # bind it to server port number   
  162.           
  163.           
  164.           
  165.     def loop(self):  
  166.         self.sockobj.listen(2# listen, allow 5 pending connects   
  167.         while(1):  
  168.             print "starting ftp service"  
  169.             self.connect,self.addr=self.sockobj.accept()  
  170.             print 'Server connected by',self.addr  
  171.             self.connect.send("220 Wellcom to CNC ftp./r/n")  
  172.             while(1):  
  173.                 self.cmd=self.connect.recv(256)  
  174.                 print 'recv: ',self.cmd  
  175.                 if not self.cmd:  
  176.                     break  
  177.                 else:  
  178.                     if(self.cmd[0:4in self.commands.keys()):  
  179.                         print "handle command ",self.cmd[0:4]  
  180.                         self.commands[self.cmd[0:4]]()  
  181.                         if(self.cmd[0:4]=="QUIT"):  
  182.                             print "client left!"  
  183.                             break  
  184.                     else:  
  185.                         self.connect.send("500 unkonw command./r/n")  
  186.             print 'closing connection',self.addr  
  187.             self.connect.close()  
  188.               
  189. if __name__ == "__main__":  
  190.     #print faitData   
  191.     ftpserver=FtpServ()  
  192.     ftpserver.loop()<PRE>  
posted @ 2011-11-08 15:44  道-法-自-然  阅读(497)  评论(0)    收藏  举报