Compared to the Basehttpserver,python TCP protocol based on the socketserver is more low-level, there is more flexibility to achieve their own functions. Here, write a small FTP server that exercises this module.
I also encountered a problem in programming, that is, recv loop received blocking problem, if the direct setblocking (0), then the last time you receive will throw an exception. Here I think the method is the communication double sends the end of the flag, through this flag to identify whether is received, the program I use File_end to mark, the basic realization of the RECV circular reception.
The following is the direct posting of the code:
Server-side Source code:
#coding =utf-8 ' use Socketserver to write FTP service functions ' Import socketserver from socketserver import threadingmixin from Socketserv ER import tcpserver import OS Import time Class Mytcphandler (Socketserver.baserequesthandler): def confirm (self,
Username,password): if username = = ' root ' and password = ' root ': return True else:
Return False def handle (self): while True:print ' Connected by%s '% self.client_address[0] Self.username = SELF.REQUEST.RECV (1024) Self.password = SELF.REQUEST.RECV (1024) self.use Rname = Self.username.strip () Self.password = Self.password.strip () print ' recv:%s%s '% (self.us
Ername,self.password) ' Login authentication ' if not (Self.username and Self.password): Break
If not self.confirm (Self.username,self.password): Self.request.send (' Auth failed! ')
Break ' Certified successful, open function ' self.request.send (' Welcome,%s! '% self.username) while True:
Self.cmd = SELF.REQUEST.RECV (1024). Strip () if not self.cmd or self.cmd = ' quit ':
Break #返回help信息 elif Self.cmd = = ' help ': Helpinfo = '
Help info\n[+]downloadfile [filename] [path]\n[+]uploadfile [filename] [path]\n[+]ls\n[+]quit\n "Self.request.sendall" (helpinfo) #执行dir命令 elif Self.cmd.sta Rtswith (' dir '): Cmd_res = Os.popen (' dir '). Read () Self.request.sendall (cmd_res + ' \ 0\n ') #下载文件 elif self.cmd.startswith (' DownloadFile '): Downloadinfo =
Self.cmd.split (') filepath = downloadinfo[1] f = open (filepath, ' RB ') If not f:break
data = F.read () data = data + ' File_end ' Self.request.sendall
(data) F.close () #上传文件 elif self.cmd.startswith (' UploadFile '):
Uploadinfo = Self.cmd.split (") filepath = uploadinfo[2] data = ' f = open (filepath, ' W ') while true:a = SELF.REQUEST.RECV (1
024) data = data + A If A.endswith (' File_end '):
F.write (A.replace (' file_end ', ')) break F.write (data)
F.close () print ' RECV file:%s '% filepath else: Pass Class Threadingsocketserver (threadingmixin,tcpserver): pass If __name__ = ' __main__ ': Serverad
Dr = (' 127.0.0.1 ', 8000) Ftpserver = TCPServer (Serveraddr,mytcphandler) ftpserver.serve_forever ()
Client Source:
#coding =utf-8 ' FTP Server client ' import socket import getpass import sys,time print ' Welcome to FTP client! ' serveraddr = (' 127.0.0.1 ', 8000) clientfd = Socket.socket (socket.af_inet,socket. SOCK_STREAM) Clientfd.connect (serveraddr) Username = raw_input (' User: ') Clientfd.sendall (Username.strip () + ' \ n ') pass Word = Getpass.getpass (' Pass: ') Clientfd.sendall (Password.strip () + ' \ n ') Infos = CLIENTFD.RECV (1024). Strip () Print info
s if infos = = ' Auth failed! ': Clientfd.close () print ' exit! '
Sys.exit () while true:cmd = Raw_input (' ftp> ') if not cmd:continue elif (' dir '):
Clientfd.send (cmd) #设置socket为非阻塞 clientfd.setblocking (0) while True:try:
#防止出错, make a fake block Time.sleep (0.3) A = CLIENTFD.RECV (1024) Print a
If not Len (a): The break except:break #将socket还原为阻塞, otherwise the following recv and send will complain ClIentfd.setblocking (1) # Print CLIENTFD.RECV (1024). Strip () elif cmd.startswith (' Help '): Clientfd.send (cmd) print clientfd.recv (1024). Strip () elif cmd.startswith (' DownloadFile '): filepath = Cmd.split (' ) [2] Clientfd.sendall (cmd) f = open (filepath, ' a ') data = ' while true:a = cl IENTFD.RECV (1024). Strip () data = Data + A If A.endswith (' File_end '): F.write (A.rep Lace (' file_end ', ') break F.write (data) f.close () print ' Downloadfile Succe Ss!
%s '% filepath elif cmd.startswith (' UploadFile '): filepath = Cmd.split (') [1] clientfd.sendall (CMD)
f = open (filepath, ' RB ') data = F.read () data = data + ' File_end ' clientfd.sendall (data) F.close () print ' UploadFile success!
%s '% filepath else:print ' Unknown service! ' Continue Clientfd.close ()