Python tcp socket 传送

发布时间:2019-09-16 07:39:01编辑:auto阅读(1758)

    【测试环境】

    os:Windows 10 x64
    Python:3.6.3


    【server.py】

    #encoding: utf-8
    #author: walker
    #date:  2017-12-01 
    #summary: 用socket创建tcp server以接收文件 
    
    import os, time
    import socket
    import struct
    
    cur_dir_fullpath = os.path.dirname(os.path.abspath(__file__))
    
    Host = '127.0.0.1'
    Port = 6789
    BufSize = 8196
    FmtHead = '256sHL'	#L决定单个文件必须小于4G
    FmtHeadLen = 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, time
    import socket
    import struct
    
    cur_dir_fullpath = os.path.dirname(os.path.abspath(__file__))
    
    Host = '127.0.0.1'
    Port = 6789
    BufSize = 8196
    FmtHead = '256sHL'	#L决定单个文件必须小于4G
    SrcRoot = 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、struct

    2、socket

    3、Socket Programming HOWTO


    *** walker的流水账 ***


关键字