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):
self.filename=filename
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
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...")
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:]))
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._lastWrite=i
# never update the hash tree