def portMappingTCP(fromIp, fromPort, toPort): # 创建socket server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(('', toPort)) server.listen(1) readableList = [server] writeableList = [] errorList = [server] # 连接客户端(侦听本机某端口) client.connect((fromIp, fromPort)) readableList.append(client) errorList.append(client) # 端口循环监听 while True: rs, ws, es = select.select(readableList, writeableList, errorList) for each in rs: # 若当前socket是server if each == server: conn, add = server.accept() print('Client IP : %s:%d' % add) readableList.append(conn) continue elif each == conn: tdata = each.recv(ConversionUtils.megabytes2Bytes(1)) client.send(tdata) elif each == client: tdata = each.recv(ConversionUtils.megabytes2Bytes(1)) conn.send(tdata)
def partitionFile(path,blockSize=128): if os.path.isdir(path): print('错误:应该是一个文件,不是一个目录') return blockBytes = ConversionUtils.megabytes2Bytes(blockSize) blockNum = IOUtils.getPartionBlockNum(path,blockSize) toPath = os.path.dirname(path) + os.sep+'MEtemp' try: os.mkdir(toPath) with open(path, 'rb') as orgFile: for i in range(int(blockNum)): print('正在分割第' + str(i + 1) + '块') totalBufferSize = 0 with open(toPath + '\\PART' + str(i), 'wb') as toFile: while totalBufferSize < blockBytes: #缓冲区大小为1M data = orgFile.read(1048576) if not data: break toFile.write(data) totalBufferSize += 1048576 print('分割完成!') except FileNotFoundError as reason: print('错误!无法创建文件!') except FileExistsError as reason: print('错误!当前目录下MEtemp目录已存在,请删除之!')
def transferSigFile(path, port=9000, bufferSize=1, verbose=True): server = socket.socket() #设置socket选项,SO_REUSEADDR让服务程序结束后立即释放端口,否则操作系统将会持有几分钟,Linux会导致异常 server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server.bind(('', port)) server.listen(5) conn, add = server.accept() if verbose: print('Client IP : %s:%d' % add) file_lock = Lock() try: bufferSize = ConversionUtils.megabytes2Bytes(bufferSize) with open(path, 'rb') as file: file_lock.acquire() if verbose: print('连接成功,开始传送文件') while True: tdata = file.read(bufferSize) if not tdata: break conn.send(tdata) if verbose: print('传输了1个文件') return 1 except (FileNotFoundError): print("文件不存在!") return 0 finally: server.close() conn.close() if not file_lock: file_lock.release()
def getPartionBlockNum(path,blockSize=128): blockBytes = ConversionUtils.megabytes2Bytes(blockSize) try: totalSize = os.path.getsize(path) except FileNotFoundError as reason: print('错误:目录不存在!') return blockNum = 0 if totalSize % blockBytes != 0: blockNum = (totalSize // blockBytes) + 1 else: blockNum = totalSize // blockBytes return blockNum
def initMetaData(self): print('计算MD5...') MD5 = IOUtils.getMD5(self.path) print(MD5) fileSize = os.path.getsize(self.path) fileName = os.path.basename(self.path) #文件大小小于100M 不分块 if fileSize < ConversionUtils.megabytes2Bytes(100): self.blockNum = 0 else: self.blockNum = IOUtils.getPartionBlockNum(self.path, self.blockSize) metadata = MetaData(fileSize, fileName, MD5, self.blockNum) self.metadataPath = os.path.dirname(self.path) + os.sep + 'METADATA' IOUtils.serializeObj2Pkl(metadata, self.metadataPath) self.fileList.append(self.metadataPath) print('元数据初始化完毕')
def receiveSigFile(path, ip, port=9000, bufferSize=1, verbose=True): client = socket.socket() while True: try: client.connect((ip, port)) break except: continue try: bufferSize = ConversionUtils.megabytes2Bytes(bufferSize) with open(path, 'wb') as file: if verbose: print("连接成功,开始接收文件") while True: tdata = client.recv(bufferSize) if not tdata: break file.write(tdata) if verbose: print('成功接收了1个文件') finally: client.close()
def serverTransferFileProcess(self): print('服务器IP为:') sip = NetUtils.getLocalIPAddr() print(sip) print('SETP1---初始化元数据') self.initMetaData() print('STEP2---测试端口连通性') self.scanPort() print('STEP3---发送元数据') NetUtils.transferSigFile(self.metadataPath) print('元数据已发送') print('STEP4---开始传输数据') if self.blockNum == 0: print('单文件<100M 传输中...请稍等...') NetUtils.transferSigFile(self.path, bufferSize=self.bufferSie, verbose=True, port=self.port) else: print('文件共分为' + str(self.blockNum) + '块,开始分割文件') blockBytes = ConversionUtils.megabytes2Bytes(self.blockSize) toPath = os.path.dirname(self.path) + os.sep + 'MEtemp' self.fileList.append(toPath) if IOUtils.isDir(toPath): print('MEtemp目录已存在,删除之') IOUtils.deleteFile(toPath) try: os.mkdir(toPath) except FileNotFoundError as reason: print('错误!无法创建目录!') sys.exit(-1) #线程池 tpool = [] #printByNoneAutoNewLine = sys.stdout with open(self.path, 'rb') as orgFile: for i in tqdm(range(self.blockNum), ascii=True): #printByNoneAutoNewLine.write('正在分割第' + str(i + 1) + '块\r\n') totalBufferSize = 0 with open(toPath + os.sep + 'PART' + str(i), 'wb') as toFile: while totalBufferSize < blockBytes: # 缓冲区 data = orgFile.read( ConversionUtils.megabytes2Bytes( self.bufferSie)) if not data: break toFile.write(data) totalBufferSize += ConversionUtils.megabytes2Bytes( self.bufferSie) self.fileList.append(toPath + os.sep + 'PART' + str(i)) #printByNoneAutoNewLine.write(toPath + os.sep+'PART' + str(i)+'\r\n') #printByNoneAutoNewLine.write('分割完成'+'\r\n') t = Thread(target=NetUtils.transferSigFile, args=(toPath + os.sep + 'PART' + str(i), self.port + i, self.bufferSie, False)) t.setDaemon(True) t.start() tpool.append(t) for eachThread in tqdm(tpool, ascii=True): while True: if not eachThread.isAlive(): break print('清理临时文件...') IOUtils.deleteFiles(self.fileList) print('完成!')