socket网络编程ftp
生活随笔
收集整理的這篇文章主要介紹了
socket网络编程ftp
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
#!/usr/bin/env python
#-*-coding:utf-8-*-
#ftp客戶端
import os
import socket
import threading
import socketserver#下載文件
def get_file(host,port,filepath):s=socket.socket()s.connect((host,port))filepath=os.path.join('.','bakc','filepath')f=open(filepath,'wb')data=Truewhile data:data=s.recv(1024)if data:f.write(data)s.close()f.close()#上傳文件
def put_file(host,port,filepath):s=socket.socket()s.connect((host,port))f=open(filepath,'rb')while True:data=f.read(1024)if data:s.sendall(data)else:breaks.close()f.close()class FtpClient:def __init__(self,host='localhost',port=21):self.host=hostself.port=portself.cmds=('QUIT','USER','NOOP','TYPE','PASV','PORT','RETR','STOR')self.linesep='\n'self.data_port=Noneself.loged=Falseself.sock=Noneself.pasv_mode=Noneself.pasv_host=Noneself.pasv_port=Nonedef cmd_connect(self):self.sock=socket.socket()self.sock.connect((self.host,self.port))self.data_port=self.sock.getsockname()[0]def start(self):print('支持的命令: ',self.cmds)self.cmd_connect()self.login()while True:cmd=input('請輸入FTP命令: ')if not cmd:print('FTP命令不能為空')continuecmd,args=self.split_args(cmd)if not self.send_cmd(cmd,args):continueres=self.readline(self.sock)print(res)if cmd.startswith('PASV') and res.startswith('227'):self.pasv_mode=Trueservinfo=res[res.index('(')+1:res.index(')')]self.pasv_host='.'.join(servinfo.split(',')[:4])servinfo=servinfo.split(',')[-2:]self.pasv_port=256*int(servinfo[0])+int(servinfo[1])if cmd.startswith('RETR'):if self.pasv_mode:threading.Thread(target=get_file,args=(self.pasv_host,self.pasv_port,args)).start()if cmd.startswitch('STOR'):if self.pasv_mode:threading.Thread(target=put_file,args=(self.pasv_host,self.pasv_port,args)).start()if cmd.startswitch('QUIT'):breakself.sock.close()self.sock=Nonedef login(self):if self.sock:self.send_cmd('USER')res=self.readline(self.sock)if res.startswitch('230'):print('登錄成功!')self.loged=Truedef readline(self,sock):data=''while not data.endswith(self.linesep):d=sock.recv(1)data+=d.decode('utf-8')return datadef split_args(self,cmds):if ' ' in cmds:cmdlsts=cmds.split(' ')cmd=cmdlsts[0]args=' '.join(cmdlists[1:])else:cmd=cmdsargs=''return cmd.upper(),argsdef send_cmd(self,cmd,args=''):if self.sock:if args:cmd=' '.join((cmd,args))if cmd.startswith('RETR') or cmd.startswith('STOR'):if self.pasv_mode is None:print('Please appoint port or stor mode.')return Falseif not args:return Falseif cmd.startswith('STOR'):if args:if not os.path.exists(args):print('File is not exists')return Falsecmd+=self.linesepsself.sock.sendall(cmd.encode('utf-8'))return Trueif __name__=='__main__':fc=FtpClient()fc.start()#!/usr/bin/env python
#-*-coding:utf-8-*-
#ftp服務(wù)器的定義
import socket
import socketserver
import time
import threading
import osclass FTPHdl(socketserver.StreamRequestHandler):def __init__(self,request=None,client_address=None,server=None):#實例屬性,所有命令self.coms_keys=('QUIT','USER','NOOP','TYPE','PASV','PORT','RETR','STOR')#命令與方法映射self.coms={}self.init_coms()self.server=server#命令端口self.cmd_port=21#數(shù)據(jù)端口self.data_port=20self.pasv_data_ip=Noneself.pasv_data_port=None#參數(shù)self.args=None#是否登入self.loged=False#主動模式,被動模式self.pasv_mode=Nonesuper().__init__(request,client_address,server)#初始話所有命令def init_coms(self):for k in self.coms_keys:self.coms[k]=getattr(self,'exe_'+k.lower())#客戶端處理def handle(self):while True:#獲得命令cmds=self.rfile.readline()if not cmds:continuecmds=cmds.decode('utf-8')#命令分析cmd=self.deal_args(cmds)#命令動詞if cmd in self.coms_keys:self.coms.get(cmd)()#不在定義的命令之內(nèi)else:self.send(500,'Invaild command.')if cmd=='QUIT':break#處理命令行def deal_args(self,cmds):#命令動詞,命令參數(shù)分割if ' ' in cmds:cmd,args=cmds.aplit(' ')args=args.strip('\n').strip()#只有命令動詞else:cmd=cmds.strip('\n')args=''#參數(shù)為空if args:self.args=args#返回命令動詞return cmd.upper()#用戶退出def exe_quit(self):self.send(221,'bye')#用戶登入def exe_user(self):user=self.args#用戶名為空或默認(rèn)if user in ('','anonymous'):user='anonymous'self.loged=True#登入已經(jīng)self.send(230,'identified!')#沒有登入,匿名else:self.send(530,'Only use anonymous')#被動模式def exe_pasv(self):if not self.loged:#要求登入self.send(332,'Please login.')return #已經(jīng)進入被動模式if self.pasv_mode:#發(fā)送用戶信息。IP端口號發(fā)送客戶端info='entering passive mode (%s)' % self.make_pasv_info()self.send(227,info)returntry:#進入被動模式self.enter_pasv()info='entering passive mode (%s)' % self.make_pasv_info()self.pasv_mode=Trueself.send(227,info)except Exception as e:print(e)self.send(500,'Failure change to passive mode.')#被動模式下數(shù)據(jù)連接服務(wù)器的地址和端口def make_pasv_info(self):ip_info=self.pasv_data_ip.split('.')ip_info=','.join(ip_info)porta=str(self.pasv_data_port // 256)portb=str(self.pasv_data_port % 256)return ','.join((ip_info,porta,portb))#進入被動模式def enter_pasv(self):if self.server.data_server is None:self.pasv_data_ip,self.pasv_data_port=self.server.create_data_server()#進入主動模式def exe_port(self):self.send(500,'Do not offer port mode.')def exe_noop(self):self.send(200,'ok')def exe_type(self):self.send(200,'ok')#下載文件def exe_retr(self):if not os.path.exists(self.args):self.send(550,'File is not exists.')returnclient_addr=self.request.getpeername()[0]#獲得ip地址self.add_opr_file(client_addr,('RETR',self.args))self.send(150,'ok.')#上傳文件def exe_stor(self):client_addr=self.request.getpeername()[0]self.add_opr_file(client_addr,('STOR',self.args))self.send(150,'ok.')def add_opr_file(self,client_addr,item):if client_addr in DataHdl.client_opr:DataHdl.client_opr[client_addr].append(item)else:DataHdl.client_opr[client_addr]=[item,]def send(self,code,info):infos='%d %s\n' % (code,info)self.request.sendall(infos.encode('utf-8'))class MyThrTCPServ(socketserver.ThreadingTCPServer):def __init__(self,addr,Hdl):self.data_server=Nonesuper().__init__(addr,Hdl)def shutdown(self):if self.data_server:threading.Thread(target=self.data_server.shutdown).start()super().shutdown()def create_data_server(self):self.data_server=socketserver.ThreadingTCPServer(('127.0.0.1',0),DataHdl)pasv_data_ip,pasv_data_port=self.data_server.server_addressthreading.Thread(target=self.data_server.serve_forever).start()return pasv_data_ip,pasv_data_portclass DataHdl(socketserver.StreamRequestHandler):client_opr={}def handle(self):peerip=self.request.getpeername()[0]opr=self.get_opr_args(peerip)if opr:if opr[0]=='RETR':#下載文件self.retr_file(opr[1])elif opr[0]=='STOR':#上傳文件self.stor_file(opr[1])def get_opr_args(self,peerip):if peerip in self.client_opr:opr=self.client_opr[peerip]if not self.client_opr[peerip]:self.client_opr.pop(peerip)return opr#發(fā)送文件def retr_file(self,filepath):f=open(filepath,'rb')while True:data=f.read(1024)if data:self.request.sendall(data)else:breakf.close()#接受文件def stor_file(self,filepath):f=open(os.path.join('.','bakt',filepath),'wb')while True:data=self.request.recv(1024)if data:f.write(data)else:breakf.close()if __name__=='__main__':server=MyThrTCPServ(('127.0.0.1',21),FTPHdl)threading.Thread(target=server.serve_forever).start()print('FTP start...')time.sleep(30)server.shutdown()
總結(jié)
以上是生活随笔為你收集整理的socket网络编程ftp的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Libevent源码分析
- 下一篇: hdu3579(中国剩余问题经典)