首页 > 编程知识 正文

python连接ftp,python实现ftp上传下载

时间:2023-05-06 16:47:48 阅读:160512 作者:2556

用python自己实现文件传输。 实际上,在python的ftplib模块中封装了实现FTP传输的功能。 但是,为了理解文件传输的结构,我决定自己写。

客户端可以将文件上传到服务器并下载。

get从服务器下载,post将文件上传到服务器。

工程主要目录:

get方法流程图:

put方法与get方法大致相同,只是客户端发送文件并由服务器接收

Put方法的流程图:

客户端代码: #-- coding : utf-8-- # # # FTP _ client # created on 2016 12 15 # @ author : Huang ping yi # # importsocketion 端口) : self.host=host self.port=portdefput ) self, msg ) 3360#putlock msgiflen(msg ) 0: remote_filename=msg[0] # 确定文件中是否存在ifOS.path.isfile ) remote_filename ) 3360file_size=OS的服务cmd _ msg=' file _ transfer|put | file_size(self.sock.send ) cmd_msg )服务器返回响应feedback=self.sock.recv(1024 ) print '--feedback: ', 返回feeedback3360 '的if feedback.starts with (file _ transfer|put|ready ' ) :f=file ) remote_filename, ' rb ' ) send_size=0 # 开始的传输每次在1024中whilenotfile _ size==send _ size 3360 if file _ size-send _ size 1024360 data=f.read (1024 ) send _ sed ize ) send _ size=file _ size-send _ size self.sock.send ) datate ) size ) send else 3360 print '-- sendfile % s % msg ) 3360#getret msgiflen(msg ) 0: remote_filename=msg[0] #服务器cmd _ msg=' file _ transfer|get|% s ' %

edback:',feedback #如果文件存在,服务器发送文件大小过来 if feedback.startswith("file_transfer|get|ready"): #文件大小 file_size = int(feedback.split("|")[-1]) #客户端发送准备接收 ack_msg = "file_transfer|get|recv|ready" self.sock.send(ack_msg) #建立文件 f = file("recv%s"% remote_filename,'wb') #客户端接受 #收到的数据和总大小比较 recv_size =0 #文件很大,接受不完,开始计数,每次接收1024 while not file_size == recv_size: if file_size-recv_size>1024: data = self.sock.recv(1024) recv_size += len(data)#收到的小于1024,实时性不一定是1024 #最后一轮 else: data = self.sock.recv(file_size-recv_size) recv_size+=file_size-recv_size f.write(data) else: print "--recv file %s " % remote_filename f.close() else: print feedback def interactive(self): #客户端交互 while True: user_input = raw_input("ftp_client::").strip() if len(user_input) == 0: continue cmd = user_input.split() if hasattr(self, cmd[0]):#用反射判断用户是要get还是put #判断对象是否有cmd[0]方法 func = getattr(self, cmd[0])#有则将cmd[0]方法赋值 func(cmd[1:])#把后面的参数传给cmd[0]方法,并执行cmd[0]函数 else:#如果是其他命令,就打印错误 print "33[31;1mWrong cmd usage!33[0m" def connect(self): #连接 self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((self.host, self.port)) self.interactive()if __name__ == '__main__': ftp = FTP('localhost',7126 ) ftp.connect()

服务器端代码: # -*- coding: utf-8 -*-### socket_server# Created on 2016 12 15# @author:huangpingyi##import SocketServerimport osclass MyTCPHandler(SocketServer.BaseRequestHandler): def handle(self): while True: data = self.request.recv(1024).strip() data = data.split("|") if hasattr(self, data[0]): func = getattr(self, data[0]) func(data[1:])#将后面参数传入file_transfer def file_transfer(self,msg): if msg[0] == "get": print "----going to send file:%s to client" % msg[1] filename = msg[1] if os.path.isfile(filename): #判断文件存在 #如果文件存在,就判断文件大小 file_size = os.path.getsize(filename) #将文件大小发送給客户端 ack_msg = "file_transfer|get|ready|%s" % file_size self.request.send(ack_msg) client_ack = self.request.recv(1024) print '-->client ack:', client_ack #如果客户端准备好就开始传输文件 if client_ack.startswith("file_transfer|get|recv|ready"): f = file(filename, "rb") send_size =0 Flag = True while Flag: if send_size+1024 > file_size: data = f.read(file_size-send_size) Flag = False else: data = f.read(1024) send_size+=1024 self.request.send(data) print '--file %s send done---' % filename f.close() else: ack_msg = "file_transfer|get|doesn't exist" self.request.send(ack_msg) if msg[0] == "put": print "----going to put file:%s" % msg[1] #获取文件名字和大小 file_name = msg[1] file_size = msg[2] base_path = "D:untitled4" #发送准备好接收的请求 ack_msg = "file_transfer|put|ready" self.request.send(ack_msg) recv_size = 0 #上传文件路径拼接 file_dir = os.path.join(base_path,file_name) f = file(file_dir,'wb') Flag = True while Flag: #未上传完毕, if int(file_size)>recv_size: #最多接收1024,可能接收的小于1024 data =self.request.recv(1024) recv_size+=len(data) #上传完毕,则退出循环 else: recv_size = 0 Flag = False continue #写入文件 f.write(data) print 'upload successed.' f.close()if __name__ == '__main__': HOST,PORT = 'localhost',7126 server = SocketServer.ThreadingTCPServer((HOST,PORT),MyTCPHandler) server.serve_forever()

测试效果:

执行get 操作

客户端:

服务器:

       

    刷新recv文件夹,便可看见test.txt

                                                                                                                                                                                                                                 


  执行put操作      

客户端:     

 

 服务器:                                                                                                                                                                                                                                                                                                       



                                                     

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。