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)