import socket from hashtree import HashTree from networkers import NetworkReader,NetworkWriter import collections import sys import logging as log import config as conf # debug copy default file import shutil origFilename=sys.argv[1] filename=origFilename+"_" shutil.copyfile(origFilename,filename) class Connection: def __init__(self,server_socket): self.socket, address = server_socket.accept() log.info('Connected by {0}'.format(address)) fr=self.socket.makefile(mode="rb") fw=self.socket.makefile(mode="wb") self.incoming=NetworkReader(fr) self.outcoming=NetworkWriter(fw) def __enter__(self): return self.incoming,self.outcoming def __exit__(self, exc_type, exc_val, exc_tb): self.socket.close() localTree=HashTree.fromFile(open(filename,mode="rb")) ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ss.bind(("",conf.port)) ss.listen(1) blocksToTransfer=[] nodeStack=collections.deque([0]) i1=-1 while True: with Connection(ss) as (incoming,outcoming): jsonData,binData=incoming.readMsg() dataFile=open(filename,mode="rb+") if jsonData["command"]=="init": assert jsonData["blockSize"]==localTree.BLOCK_SIZE assert jsonData["blockCount"]==localTree.leafCount elif jsonData["command"]=="req": # !! index out of range log.info("received request for node #{0}".format(jsonData["index"])) nodeHash=localTree.store[jsonData["index"]] jsonResponse={"command":"send", "index":jsonData["index"], "dataType":"hash"} binResponse=nodeHash outcoming.writeMsg(jsonResponse,binResponse) elif jsonData["command"]=="send" and jsonData["dataType"]=="data": # needlessly allow hashes and data in mixed order log.info("received data block #{0}: {1}...{2}".format(jsonData["index"],binData[:5],binData[-5:])) i2=jsonData["index"] if i1+1!=i2: dataFile.seek(i2*localTree.BLOCK_SIZE) dataFile.write(binData) i1=i2 # never update the hash tree elif jsonData["command"]=="end": log.info("closing session...") break else: pass # !! error dataFile.close() sys.exit(0)