from hashtree import HashTree
import collections
import socket
import sys
import config as conf
from networkers import NetworkReader,NetworkWriter
def connect():
HOST = conf.hosts[0] # The remote host
PORT = conf.port # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
fr=s.makefile(mode='rb')
fw=s.makefile(mode='wb')
networkReader=NetworkReader(fr)
networkReader.start()
networkWriter=NetworkWriter(fw)
networkWriter.start()
incoming=networkReader.output # synchronized message queue
outcoming=networkWriter.input
return (s,incoming,outcoming)
def negotiate(incoming,outcoming):
localTree=HashTree.fromFile(open("clientFile.txt",mode="rb"))
blocksToTransfer=[]
nodeStack=collections.deque([0]) # root
# initialize session
jsonData={"command":"init", "blockSize":localTree.BLOCK_SIZE, "blockCount":localTree.leafCount, "version":conf.version}
outcoming.put((jsonData,b""))
# determine which blocks to send
while len(nodeStack)>0:
i=nodeStack.pop()
jsonData={"command":"req", "index":i}
outcoming.put((jsonData,b""))
jsonData,binData=incoming.get(timeout=2)
assert jsonData["index"]==i
assert jsonData["dataType"]=="hash"
if localTree.store[i]!=binData:
if 2*i+3<len(localTree.store): # inner node
nodeStack.append(2*i+2)
nodeStack.append(2*i+1)
else: blocksToTransfer.append(i-localTree.leafStart) # leaf
return blocksToTransfer
def sendData(outcoming,blocksToTransfer):
print(blocksToTransfer)
dataFile=open("clientFile.txt",mode="rb")
for i in blocksToTransfer:
jsonData={"command":"send", "index":i, "dataType":"data"}
dataFile.seek(i*HashTree.BLOCK_SIZE)
binData=dataFile.read(HashTree.BLOCK_SIZE)
print("block #{0}: {1}...{2}".format(i,binData[:5],binData[-5:]))
outcoming.put((jsonData,binData),timeout=2)
jsonData={"command":"end"}
outcoming.put((jsonData,b""),timeout=2)
outcoming.put(None)
print("closing...")
dataFile.close()
if __name__=="__main__":
sock,incoming,outcoming = connect()
blocksToTransfer=negotiate(incoming,outcoming)
sendData(outcoming,blocksToTransfer)
sock.close()
sys.exit(0)