diff --git a/src/client.py b/src/client.py --- a/src/client.py +++ b/src/client.py @@ -40,11 +40,12 @@ class Client: with Connection() as (incoming,outcoming): jsonData={"command":"init", "blockSize":localTree.BLOCK_SIZE, "blockCount":localTree.leafCount, "version":conf.version} outcoming.writeMsg(jsonData) + jsonData,binData=incoming.readMsg() + assert jsonData["command"]=="ack" - # determine which blocks to send - print(datetime.now(), "negotiating:") - while len(nodeStack)>0: - with Connection() as (incoming,outcoming): + # determine which blocks to send + print(datetime.now(), "negotiating:") + while len(nodeStack)>0: i=nodeStack.pop() outcoming.writeMsg({"command":"req", "index":i}) @@ -69,8 +70,8 @@ class Client: i1=-1 print(datetime.now(), "sending data:") - for (k,i2) in enumerate(blocksToTransfer): - with Connection() as (incoming,outcoming): + with Connection() as (incoming,outcoming): + for (k,i2) in enumerate(blocksToTransfer): jsonData={"command":"send", "index":i2, "dataType":"data"} if i1+1!=i2: dataFile.seek(i2*HashTree.BLOCK_SIZE) @@ -79,12 +80,14 @@ class Client: log.info("block #{0}: {1}...{2}".format(i2,binData[:5],binData[-5:])) outcoming.writeMsg(jsonData,binData) - i1=i2 - progress(k,len(blocksToTransfer)) + jsonData,binData=incoming.readMsg() + assert jsonData["command"]=="ack" and jsonData["index"]==i2, jsonData + i1=i2 + progress(k,len(blocksToTransfer)) print("100%") with Connection() as (incoming,outcoming): outcoming.writeMsg({"command":"end"}) - log.info(datetime.now(), "closing session...") + log.info("closing session...") dataFile.close() diff --git a/src/networkers.py b/src/networkers.py --- a/src/networkers.py +++ b/src/networkers.py @@ -7,14 +7,16 @@ class NetworkReader: def readMsg(self): data=self.stream.readline() - if not data: pass # !! raise something + assert data jsonLength=int(data.split(b":")[1].strip()) # "json-length: length" -> length data=self.stream.readline() - if not data: pass # !! raise something + assert data binLength=int(data.split(b":")[1].strip()) # "bin-length: length" -> length jsonData=self.stream.read(jsonLength) + assert len(jsonData)==jsonLength jsonData=json.loads(str(jsonData,encoding="utf-8")) binData=self.stream.read(binLength) + assert len(binData)==binLength return (jsonData,binData) @@ -31,4 +33,5 @@ class NetworkWriter: jsonData=bytes(json.dumps(jsonData)+"\n",encoding="utf-8") jsonLength=bytes("json-length: "+str(len(jsonData))+"\n",encoding="utf-8") binLength=bytes("bin-length: "+str(len(binData))+"\n",encoding="utf-8") + return b"".join((jsonLength,binLength,jsonData,binData)) diff --git a/src/server.py b/src/server.py --- a/src/server.py +++ b/src/server.py @@ -42,33 +42,38 @@ class Server: self.dataFile=None def serve(self): - while self._serveOne(): - pass - - def _serveOne(self): - with Connection(self.ss) as (incoming,outcoming): - jsonData,binData=incoming.readMsg() + while True: + with Connection(self.ss) as (incoming,outcoming): + try: + while True: + if not self._serveOne(incoming,outcoming): return + except AssertionError: + continue - if jsonData["command"]=="init": - assert jsonData["blockSize"]==self.BLOCK_SIZE - assert jsonData["blockCount"]==self.tree.leafCount + def _serveOne(self,incoming,outcoming): + jsonData,binData=incoming.readMsg() - elif jsonData["command"]=="req": - outcoming.writeMsg(*self._requestHash(jsonData)) + if jsonData["command"]=="init": + assert jsonData["blockSize"]==self.BLOCK_SIZE + assert jsonData["blockCount"]==self.tree.leafCount + outcoming.writeMsg({"command": "ack"}) - elif jsonData["command"]=="send" and jsonData["dataType"]=="data": - self._receiveData(jsonData,binData) + 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": - log.info("closing session...") - if self.dataFile: - self.dataFile.close() - return False + elif jsonData["command"]=="end": + log.info("closing session...") + if self.dataFile: + self.dataFile.close() + return False - else: - assert False, jsonData["command"] + else: + assert False, jsonData["command"] - return True + return True def _requestHash(self,jsonData): log.info("received request for node #{0}".format(jsonData["index"])) @@ -91,4 +96,5 @@ class Server: self.dataFile.write(binData) self._lastWrite=i + return ({"command": "ack", "index": i},) # never update the hash tree