【测试环境】

os:Windows 10 x64Python:3.6.3

【server.py】

#encoding: utf-8#author: walker#date:  2017-12-01 #summary: 用socket创建tcp server以接收文件 import os, timeimport socketimport structcur_dir_fullpath = os.path.dirname(os.path.abspath(__file__))Host = '127.0.0.1'Port = 6789BufSize = 8196FmtHead = '256sHL'	#L决定单个文件必须小于4GFmtHeadLen = struct.calcsize(FmtHead)DstRoot = os.path.join(cur_dir_fullpath, 'output')	#目标目录StartTime = time.time()		#开始时间		def ProcAll():		cnt = 0		fileSizeTotal = 0		sockServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)		sockServer.bind((Host, Port))		print('Listen prot %d ...' % Port)		sockServer.listen(1)		sock, addr = sockServer.accept()		print('local: %s:%d' % (sock.getsockname()))		print('client: %s:%d' % addr)		while True:			#接收数据包头(相对路径,相对路径长度,文件大小)			pkgHead = sock.recv(FmtHeadLen)			relPath, relPathLen, fileSize = struct.unpack(FmtHead, pkgHead)			relPath = relPath.decode('utf8')[0:relPathLen]			if relPath == 'OVER' and fileSize == 0:				print('All file recv over!')				break			pathfile = os.path.join(DstRoot, relPath)			dstDir = os.path.dirname(pathfile)			if not os.path.exists(dstDir):				os.makedirs(dstDir)			with open(pathfile, mode='wb') as f:				recvSize = 0	#单文件已接收字节数				while True:					if recvSize >= fileSize:						break					bufSize = BufSize					if fileSize - recvSize < BufSize:	#剩余字节数小于BufSize						bufSize = fileSize - recvSize					buf = sock.recv(bufSize)					f.write(buf)					recvSize += len(buf)				fileSizeTotal += recvSize			cnt += 1			print('cnt: %d, time cost: %.2fs, %s'% (cnt, time.time()-StartTime, pathfile))							sock.close()		sockServer.close()				print('cnt: %d, time total: %.2fs, send bytes:%ld B'% (cnt, time.time()-StartTime, fileSizeTotal))if __name__ == '__main__':	ProcAll()		print('Time total:%.2fs' % (time.time() - StartTime))

【client.py】

#encoding: utf-8#author: walker#date: 2017-12-01 #summary: 用socket连接tcp server以传送文件import os, timeimport socketimport structcur_dir_fullpath = os.path.dirname(os.path.abspath(__file__))Host = '127.0.0.1'Port = 6789BufSize = 8196FmtHead = '256sHL'	#L决定单个文件必须小于4GSrcRoot = os.path.join(cur_dir_fullpath, 'input')	#源目录ExtSet = {'.pdf', '.html', '.htm'}		#后缀列表StartTime = time.time()		#开始时间def ProcAll():	cnt = 0	fileSizeTotal = 0	sockClient = socket.socket(socket.AF_INET, socket.SOCK_STREAM)	print('Connect %s:%d ...' % (Host, Port))	sockClient.connect((Host, Port))	print('local: %s:%d' % (sockClient.getsockname()))	for parent, dirnames, filenames in os.walk(SrcRoot):		for filename in filenames:			if os.path.splitext(filename)[1].lower() not in ExtSet:	#排除非指定后缀的文件				continue			pathfile = os.path.join(parent, filename)			relPath = pathfile[len(SrcRoot):].strip(os.path.sep)	#相对路径(相对于SrcRoot)			fileSize = os.path.getsize(pathfile)			#发送数据包头(相对路径,相对路径长度,文件大小)			pkgHead = struct.pack(FmtHead, relPath.encode('utf8'), len(relPath), fileSize)			sockClient.sendall(pkgHead)			with open(pathfile, mode='rb') as f:				while True:					buf = f.read(BufSize)					if len(buf) < 1:						break					sockClient.sendall(buf)			fileSizeTotal += fileSize			cnt += 1			print('cnt: %d, time cost: %.2fs, %s'% (cnt, time.time()-StartTime, pathfile))		#发送文件传送结束消息	pkgHead = struct.pack(FmtHead, 'OVER'.encode('utf8'), len('OVER'), 0)	sockClient.sendall(pkgHead)		sockClient.close()		print('cnt: %d, time total: %.2fs, send bytes:%ld B'% (cnt, time.time()-StartTime, fileSizeTotal))	if __name__ == '__main__':            ProcAll()        print('Time total:%.2fs' % (time.time() - StartTime))

【相关阅读】

1、

2、

3、

*** ***