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