基于python3实现socket文件传输和校验
基于socket的文件传输并进行MD5值校验,供大家参考,具体内容如下
文件传输分为两个类,一个是服务端,一个是客户端。
客户端发起发送文件或接收文件的请求,服务端收到请求后接收或发送文件,最后进行MD5值的校验
socket数据通过struct模块打包
需要发送文件到服务端时,调用sendFile函数,struct包内包含文件信息、文件大小、文件MD5等信息,服务端接收到文件后进行MD5值校验,校验成功后则返回成功
需要从服务器下载文件时,调用recvFile函数,收到文件后进行MD5校验
client类代码如下
importsocket importstruct,os importsubprocess dataFormat='8s32s100s100sl' classfileClient(): def__init__(self,addr): self.addr=addr self.action='' self.fileName='' self.md5sum='' self.clientfilePath='' self.serverfilePath='' self.size=0 defstruct_pack(self): ret=struct.pack(dataFormat,self.action.encode(),self.md5sum.encode(),self.clientfilePath.encode(), self.serverfilePath.encode(),self.size) returnret defstruct_unpack(self,package): self.action,self.md5sum,self.clientfilePath,self.serverfilePath,self.size=struct.unpack(dataFormat,package) self.action=self.action.decode().strip('\x00') self.md5sum=self.md5sum.decode().strip('\x00') self.clientfilePath=self.clientfilePath.decode().strip('\x00') self.serverfilePath=self.serverfilePath.decode().strip('\x00') defsendFile(self,clientfile,serverfile): ifnotos.path.exists(clientfile): print('源文件/文件夹不存在') return"Nosuchfileordirectory" self.action='upload' (status,output)=subprocess.getstatusoutput("md5sum"+clientfile+"|awk'{printf$1}'") ifstatus==0: self.md5sum=output else: return"md5sumerror:"+status self.size=os.stat(clientfile).st_size self.serverfilePath=serverfile self.clientfilePath=clientfile ret=self.struct_pack() s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) try: s.connect(self.addr) s.send(ret) recv=s.recv(1024) ifrecv.decode()=='dirNotExist': print("目标文件/文件夹不存在") return"Nosuchfileordirectory" elifrecv.decode()=='ok': fo=open(clientfile,'rb') whileTrue: filedata=fo.read(1024) ifnotfiledata: break s.send(filedata) fo.close() recv=s.recv(1024) ifrecv.decode()=='ok': print("文件传输成功") s.close() return0 else: s.close() return"md5sumerror:md5sumisnotcorrect!" exceptExceptionase: print(e) return"error:"+str(e) defrecvFile(self,clientfile,serverfile): ifnotos.path.isdir(clientfile): filePath,fileName=os.path.split(clientfile) else: filePath=clientfile ifnotos.path.exists(filePath): print('本地目标文件/文件夹不存在') return"Nosuchfileordirectory" self.action='download' self.clientfilePath=clientfile self.serverfilePath=serverfile s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) try: s.connect(self.addr) ret=self.struct_pack() s.send(ret) recv=s.recv(struct.calcsize(dataFormat)) self.struct_unpack(recv) ifself.action.startswith("ok"): ifos.path.isdir(clientfile): fileName=(os.path.split(serverfile))[1] clientfile=os.path.join(clientfile,fileName) self.recvd_size=0 file=open(clientfile,'wb') whilenotself.recvd_size==self.size: ifself.size-self.recvd_size>1024: rdata=s.recv(1024) self.recvd_size+=len(rdata) else: rdata=s.recv(self.size-self.recvd_size) self.recvd_size=self.size file.write(rdata) file.close() print('\n等待校验...') (status,output)=subprocess.getstatusoutput("md5sum"+clientfile+"|awk'{printf$1}'") ifoutput==self.md5sum: print("文件传输成功") else: print("文件校验不通过") (status,output)=subprocess.getstatusoutput("rm"+clientfile) elifself.action.startswith("nofile"): print('远程源文件/文件夹不存在') return"Nosuchfileordirectory" exceptExceptionase: print(e) return"error:"+str(e)
server类代码如下
importsocket importstruct,os importsubprocess importsocketserver dataFormat='8s32s100s100sl' classfileServer(socketserver.StreamRequestHandler): defstruct_pack(self): ret=struct.pack(dataFormat,self.action.encode(),self.md5sum.encode(),self.clientfilePath.encode(), self.serverfilePath.encode(),self.size) returnret defstruct_unpack(self,package): self.action,self.md5sum,self.clientfilePath,self.serverfilePath,self.size=struct.unpack(dataFormat, package) self.action=self.action.decode().strip('\x00') self.md5sum=self.md5sum.decode().strip('\x00') self.clientfilePath=self.clientfilePath.decode().strip('\x00') self.serverfilePath=self.serverfilePath.decode().strip('\x00') defhandle(self): print('connectedfrom:',self.client_address) fileinfo_size=struct.calcsize(dataFormat) self.buf=self.request.recv(fileinfo_size) ifself.buf: self.struct_unpack(self.buf) print("getaction:"+self.action) ifself.action.startswith("upload"): try: ifos.path.isdir(self.serverfilePath): fileName=(os.path.split(self.clientfilePath))[1] self.serverfilePath=os.path.join(self.serverfilePath,fileName) filePath,fileName=os.path.split(self.serverfilePath) ifnotos.path.exists(filePath): self.request.send(str.encode('dirNotExist')) else: self.request.send(str.encode('ok')) recvd_size=0 file=open(self.serverfilePath,'wb') whilenotrecvd_size==self.size: ifself.size-recvd_size>1024: rdata=self.request.recv(1024) recvd_size+=len(rdata) else: rdata=self.request.recv(self.size-recvd_size) recvd_size=self.size file.write(rdata) file.close() (status,output)=subprocess.getstatusoutput("md5sum"+self.serverfilePath+"|awk'{printf$1}'") ifoutput==self.md5sum: self.request.send(str.encode('ok')) else: self.request.send(str.encode('md5sumerror')) exceptExceptionase: print(e) finally: self.request.close() elifself.action.startswith("download"): try: ifos.path.exists(self.serverfilePath): (status,output)=subprocess.getstatusoutput("md5sum"+self.serverfilePath+"|awk'{printf$1}'") ifstatus==0: self.md5sum=output self.action='ok' self.size=os.stat(self.serverfilePath).st_size ret=self.struct_pack() self.request.send(ret) fo=open(self.serverfilePath,'rb') whileTrue: filedata=fo.read(1024) ifnotfiledata: break self.request.send(filedata) fo.close() else: self.action='nofile' ret=self.struct_pack() self.request.send(ret) exceptExceptionase: print(e) finally: self.request.close()
调用server,并开启服务
importfileSocket importthreading importsocketserver importtime serverIp='127.0.0.1' serverPort=19821 serverAddr=(serverIp,serverPort) classfileServerth(threading.Thread): def__init__(self): threading.Thread.__init__(self) self.create_time=time.time() self.local=threading.local() defrun(self): print("fileServerisrunning...") fileserver.serve_forever() fileserver=socketserver.ThreadingTCPServer(serverAddr,fileSocket.fileServer) fileserverth=fileServerth() fileserverth.start()
调用client,发送/接受文件
importfileSocket serverIp='127.0.0.1' serverPort=19821 serverAddr=(serverIp,serverPort) fileclient=fileSocket.fileClient(serverAddr) fileclient.sendFile('fromClientPath/file','toServerPath/file') fileclient.recvFile('toClientPath/file','fromServerPath/file')
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。