Changeset - 8b0dc65400f3
[Not reviewed]
default
0 2 0
Laman - 8 years ago 2017-05-08 01:01:52

server accepting saved tree, fixed missing seeks
2 files changed with 22 insertions and 11 deletions:
0 comments (0 inline, 0 general)
src/morevna.py
Show inline comments
 
import sys
 
import os.path
 
from argparse import ArgumentParser
 

	
 
from hashtree import HashTree
 
from client import Client
 
from server import Server
 

	
 

	
 
def _checkDatafile(datafile):
 
	if not os.path.isfile(datafile):
 
		print("invalid file specified:",args.datafile,file=sys.stderr)
 
def _checkFile(f):
 
	if not os.path.isfile(f):
 
		print("invalid file specified:",f,file=sys.stderr)
 
		sys.exit(1)
 

	
 

	
 
def buildTree(args):
 
	_checkDatafile(args.datafile)
 
	_checkFile(args.datafile)
 

	
 
	tree=HashTree.fromFile(args.datafile)
 
	tree.save(args.treefile)
 

	
 
def update(args):
 
	_checkDatafile(args.datafile)
 
	_checkFile(args.datafile)
 

	
 
	c=Client(args.datafile)
 
	blocksToTransfer=c.negotiate()
 
	c.sendData(blocksToTransfer)
 

	
 
def serve(args):
 
	_checkDatafile(args.datafile)
 
	_checkFile(args.datafile)
 
	if args.tree:
 
		_checkFile(args.tree)
 

	
 
	# debug copy default file
 
	import shutil
 
	origFilename=args.datafile
 
	filename=origFilename+"_"
 
	shutil.copyfile(origFilename,filename)
 

	
 
	s=Server(filename)
 
	s=Server(filename,args.tree)
 
	s.serve()
 

	
 

	
 
parser=ArgumentParser()
 
subparsers=parser.add_subparsers()
 

	
 
pRebuild=subparsers.add_parser("build")
 
pRebuild.add_argument("treefile",help="stored hash tree location")
 
pRebuild.add_argument("datafile")
 
pRebuild.set_defaults(func=buildTree)
 

	
 
pUpdate=subparsers.add_parser("update")
src/server.py
Show inline comments
 
@@ -15,71 +15,80 @@ class Connection:
 

	
 
		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 Server:
 
	def __init__(self,filename):
 
	def __init__(self,filename,treeFile=""):
 
		self.filename=filename
 

	
 
		if treeFile:
 
			self.tree=HashTree.load(treeFile)
 
		else:
 
		self.tree=HashTree.fromFile(filename)
 

	
 
		self.BLOCK_SIZE=self.tree.BLOCK_SIZE
 

	
 
		self.ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 
		self.ss.bind(("",conf.port))
 
		self.ss.listen(1)
 

	
 
		self._lastWrite=-1
 
		self.dataFile=None
 

	
 
	def serve(self):
 
		while self._serveOne():
 
			pass
 

	
 
	def _serveOne(self):
 
		with Connection(self.ss) as (incoming,outcoming):
 
			jsonData,binData=incoming.readMsg()
 

	
 
			if jsonData["command"]=="init":
 
				assert jsonData["blockSize"]==self.BLOCK_SIZE
 
				assert jsonData["blockCount"]==self.tree.leafCount
 

	
 
			elif jsonData["command"]=="req":
 
				outcoming.writeMsg(*self._requestHash(jsonData))
 

	
 
			elif jsonData["command"]=="send" and jsonData["dataType"]=="data":
 
				self._receiveData(jsonData,binData)
 

	
 
			elif jsonData["command"]=="end":
 
				log.info("closing session...")
 
				if self.dataFile:
 
					self.dataFile.close()
 
				return False
 

	
 
			else:
 
				assert False, jsonData["command"]
 

	
 
			return True
 

	
 
	def _requestHash(self,jsonData):
 
		log.info("received request for node #{0}".format(jsonData["index"]))
 
		assert jsonData["index"]<len(self.tree.store)
 
		nodeHash=self.tree.store[jsonData["index"]]
 

	
 
		jsonResponse={"command":"send", "index":jsonData["index"], "dataType":"hash"}
 
		binResponse=nodeHash
 

	
 
		return (jsonResponse,binResponse)
 

	
 
	def _receiveData(self,jsonData,binData):
 
		log.info("received data block #{0}: {1}...{2}".format(jsonData["index"],binData[:5],binData[-5:]))
 

	
 
		if not self.dataFile:
 
			self.dataFile=open(self.filename,mode="rb+")
 
		i=jsonData["index"]
 
		with open(self.filename,mode="rb+") as dataFile:
 
			if self._lastWrite+1!=i:
 
				dataFile.seek(i*self.BLOCK_SIZE)
 
			dataFile.write(binData)
 
			self.dataFile.seek(i*self.BLOCK_SIZE)
 
		self.dataFile.write(binData)
 
		self._lastWrite=i
 

	
 
		# never update the hash tree
0 comments (0 inline, 0 general)