Files @ 8b0dc65400f3
Branch filter:

Location: Morevna/src/client.py

Laman
server accepting saved tree, fixed missing seeks
from hashtree import HashTree
import collections
import socket
import sys
import logging as log

import config as conf
from networkers import NetworkReader,NetworkWriter


class Connection:
	def __init__(self):
		self.socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
		self.socket.connect((conf.hosts[0], conf.port))
		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()


class Client:
	def __init__(self,filename):
		self.filename=filename

	def negotiate(self):
		localTree=HashTree.fromFile(self.filename)
		blocksToTransfer=[]
		nodeStack=collections.deque([0]) # root

		# initialize session
		with Connection() as (incoming,outcoming):
			jsonData={"command":"init", "blockSize":localTree.BLOCK_SIZE, "blockCount":localTree.leafCount, "version":conf.version}
			outcoming.writeMsg(jsonData)

		# determine which blocks to send
		while len(nodeStack)>0:
			with Connection() as (incoming,outcoming):
				i=nodeStack.pop()
				outcoming.writeMsg({"command":"req", "index":i})

				jsonData,binData=incoming.readMsg()
				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(self,blocksToTransfer):
		log.info(blocksToTransfer)
		dataFile=open(self.filename,mode="rb")
		i1=-1

		for i2 in blocksToTransfer:
			with Connection() as (incoming,outcoming):
				jsonData={"command":"send", "index":i2, "dataType":"data"}
				if i1+1!=i2:
					dataFile.seek(i2*HashTree.BLOCK_SIZE)
				binData=dataFile.read(HashTree.BLOCK_SIZE)

				log.info("block #{0}: {1}...{2}".format(i2,binData[:5],binData[-5:]))

				outcoming.writeMsg(jsonData,binData)
				i1=i2

		with Connection() as (incoming,outcoming):
			outcoming.writeMsg({"command":"end"})

		log.info("closing session...")
		dataFile.close()