Files @ 802cbad78f7d
Branch filter:

Location: Morevna/src/server.py - annotation

Laman
benchmarking
import socket
from hashtree import HashTree
from networkers import NetworkReader,NetworkWriter
import logging as log

import config as conf


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()


class Server:
	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"]
		if self._lastWrite+1!=i:
			self.dataFile.seek(i*self.BLOCK_SIZE)
		self.dataFile.write(binData)
		self._lastWrite=i

		# never update the hash tree