基于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')
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。