import hashlib import socket import logging as log from hashtree import HashTree from networkers import NetworkReader,NetworkWriter import config as conf class Connection: def __init__(self,serverSocket): self._socket, address = serverSocket.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 self._treeFile=treeFile if treeFile: self._tree=HashTree.load(treeFile) else: self._tree=HashTree.fromFile(filename) self._newLeaves=dict() 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 True: with Connection(self._ss) as (incoming, outcoming): try: while True: if not self._serveOne(incoming,outcoming): return except AssertionError: continue def _serveOne(self,incoming,outcoming): jsonData,binData=incoming.readMsg() if jsonData["command"]=="init": assert jsonData["blockSize"]==self.BLOCK_SIZE assert jsonData["blockCount"]==self._tree.leafCount outcoming.writeMsg({"command": "ack"}) elif jsonData["command"]=="req": outcoming.writeMsg(*self._requestHash(jsonData)) elif jsonData["command"]=="send" and jsonData["dataType"]=="data": outcoming.writeMsg(*self._receiveData(jsonData,binData)) elif jsonData["command"]=="end": self._finalize() 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"]