基于socket的文件传输并进行MD5值校验,供大家参考,具体内容如下
文件传输分为两个类,一个是服务端,一个是客户端。
客户端发起发送文件或接收文件的请求,服务端收到请求后接收或发送文件,最后进行MD5值的校验
socket数据通过struct模块打包
需要发送文件到服务端时,调用sendFile函数,struct包内包含文件信息、文件大小、文件MD5等信息,服务端接收到文件后进行MD5值校验,校验成功后则返回成功
需要从服务器下载文件时,调用recvFile函数,收到文件后进行MD5校验
client类代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
import socket
import struct,os
import subprocess
dataFormat = '8s32s100s100sl'
class fileClient():
def __init__( self ,addr):
self .addr = addr
self .action = ''
self .fileName = ''
self .md5sum = ''
self .clientfilePath = ''
self .serverfilePath = ''
self .size = 0
def struct_pack( self ):
ret = struct.pack(dataFormat, self .action.encode(), self .md5sum.encode(), self .clientfilePath.encode(),
self .serverfilePath.encode(), self .size)
return ret
def struct_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' )
def sendFile( self ,clientfile,serverfile):
if not os.path.exists(clientfile):
print ( '源文件/文件夹不存在' )
return "No such file or directory"
self .action = 'upload'
(status, output) = subprocess.getstatusoutput( "md5sum " + clientfile + " | awk '{printf $1}'" )
if status = = 0 :
self .md5sum = output
else :
return "md5sum error:" + 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 )
if recv.decode() = = 'dirNotExist' :
print ( "目标文件/文件夹不存在" )
return "No such file or directory"
elif recv.decode() = = 'ok' :
fo = open (clientfile, 'rb' )
while True :
filedata = fo.read( 1024 )
if not filedata:
break
s.send(filedata)
fo.close()
recv = s.recv( 1024 )
if recv.decode() = = 'ok' :
print ( "文件传输成功" )
s.close()
return 0
else :
s.close()
return "md5sum error:md5sum is not correct!"
except Exception as e:
print (e)
return "error:" + str (e)
def recvFile( self ,clientfile,serverfile):
if not os.path.isdir(clientfile):
filePath,fileName = os.path.split(clientfile)
else :
filePath = clientfile
if not os.path.exists(filePath):
print ( '本地目标文件/文件夹不存在' )
return "No such file or directory"
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)
if self .action.startswith( "ok" ):
if os.path.isdir(clientfile):
fileName = (os.path.split(serverfile))[ 1 ]
clientfile = os.path.join(clientfile, fileName)
self .recvd_size = 0
file = open (clientfile, 'wb' )
while not self .recvd_size = = self .size:
if self .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}'" )
if output = = self .md5sum:
print ( "文件传输成功" )
else :
print ( "文件校验不通过" )
(status, output) = subprocess.getstatusoutput( "rm " + clientfile)
elif self .action.startswith( "nofile" ):
print ( '远程源文件/文件夹不存在' )
return "No such file or directory"
except Exception as e:
print (e)
return "error:" + str (e)
|
server类代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
import socket
import struct,os
import subprocess
import socketserver
dataFormat = '8s32s100s100sl'
class fileServer(socketserver.StreamRequestHandler):
def struct_pack( self ):
ret = struct.pack(dataFormat, self .action.encode(), self .md5sum.encode(), self .clientfilePath.encode(),
self .serverfilePath.encode(), self .size)
return ret
def struct_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' )
def handle( self ):
print ( 'connected from:' , self .client_address)
fileinfo_size = struct.calcsize(dataFormat)
self .buf = self .request.recv(fileinfo_size)
if self .buf:
self .struct_unpack( self .buf)
print ( "get action:" + self .action)
if self .action.startswith( "upload" ):
try :
if os.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)
if not os.path.exists(filePath):
self .request.send( str .encode( 'dirNotExist' ))
else :
self .request.send( str .encode( 'ok' ))
recvd_size = 0
file = open ( self .serverfilePath, 'wb' )
while not recvd_size = = self .size:
if self .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}'" )
if output = = self .md5sum:
self .request.send( str .encode( 'ok' ))
else :
self .request.send( str .encode( 'md5sum error' ))
except Exception as e:
print (e)
finally :
self .request.close()
elif self .action.startswith( "download" ):
try :
if os.path.exists( self .serverfilePath):
(status, output) = subprocess.getstatusoutput( "md5sum " + self .serverfilePath + " | awk '{printf $1}'" )
if status = = 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' )
while True :
filedata = fo.read( 1024 )
if not filedata:
break
self .request.send(filedata)
fo.close()
else :
self .action = 'nofile'
ret = self .struct_pack()
self .request.send(ret)
except Exception as e:
print (e)
finally :
self .request.close()
|
调用server,并开启服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import fileSocket
import threading
import socketserver
import time
serverIp = '127.0.0.1'
serverPort = 19821
serverAddr = (serverIp,serverPort)
class fileServerth(threading.Thread):
def __init__( self ):
threading.Thread.__init__( self )
self .create_time = time.time()
self .local = threading.local()
def run( self ):
print ( "fileServer is running..." )
fileserver.serve_forever()
fileserver = socketserver.ThreadingTCPServer(serverAddr, fileSocket.fileServer)
fileserverth = fileServerth()
fileserverth.start()
|
调用client,发送/接受文件
1
2
3
4
5
6
7
8
9
|
import fileSocket
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' )
|
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/qq_20468343/article/details/77938802