基于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