def sendData(self, uData, prefix=b""): self.__updateLastActionTimestamp() sCodedData = MixedEncode.encode(uData) if isinstance(sCodedData, six.text_type): sCodedData = sCodedData.encode() dataToSend = b"".join( [prefix, str(len(sCodedData)).encode(), b":", sCodedData]) for index in range(0, len(dataToSend), self.packetSize): bytesToSend = min(self.packetSize, len(dataToSend) - index) packSentBytes = 0 while packSentBytes < bytesToSend: try: result = self._write( dataToSend[index + packSentBytes:index + bytesToSend]) if not result["OK"]: return result sentBytes = result["Value"] except Exception as e: return S_ERROR("Exception while sending data: %s" % e) if sentBytes == 0: return S_ERROR("Connection closed by peer") packSentBytes += sentBytes del sCodedData sCodedData = None return S_OK()
def sendData(self, uData, prefix=False): self.__updateLastActionTimestamp() sCodedData = MixedEncode.encode(uData) if prefix: dataToSend = "%s%s:%s" % (prefix, len(sCodedData), sCodedData) else: dataToSend = "%s:%s" % (len(sCodedData), sCodedData) for index in range(0, len(dataToSend), self.packetSize): bytesToSend = min(self.packetSize, len(dataToSend) - index) packSentBytes = 0 while packSentBytes < bytesToSend: try: result = self._write( dataToSend[index + packSentBytes:index + bytesToSend]) if not result['OK']: return result sentBytes = result['Value'] except Exception as e: return S_ERROR("Exception while sending data: %s" % e) if sentBytes == 0: return S_ERROR("Connection closed by peer") packSentBytes += sentBytes del sCodedData sCodedData = None return S_OK()
def receiveData(self, maxBufferSize=0, blockAfterKeepAlive=True, idleReceive=False): self.__updateLastActionTimestamp() if self.receivedMessages: return self.receivedMessages.pop(0) # Buffer size can't be less than 0 maxBufferSize = max(maxBufferSize, 0) try: # Look either for message length of keep alive magic string iSeparatorPosition = self.byteStream.find(b":", 0, 10) keepAliveMagicLen = len(BaseTransport.keepAliveMagic) isKeepAlive = self.byteStream.find(BaseTransport.keepAliveMagic, 0, keepAliveMagicLen) == 0 # While not found the message length or the ka, keep receiving while iSeparatorPosition == -1 and not isKeepAlive: retVal = self._read(16384) # If error return if not retVal["OK"]: return retVal # If closed return error if not retVal["Value"]: return S_ERROR("Peer closed connection") # New data! self.byteStream += retVal["Value"] # Look again for either message length of ka magic string iSeparatorPosition = self.byteStream.find(b":", 0, 10) isKeepAlive = self.byteStream.find( BaseTransport.keepAliveMagic, 0, keepAliveMagicLen) == 0 # Over the limit? if maxBufferSize and len( self.byteStream ) > maxBufferSize and iSeparatorPosition == -1: return S_ERROR("Read limit exceeded (%s chars)" % maxBufferSize) # Keep alive magic! if isKeepAlive: gLogger.debug("Received keep alive header") # Remove the ka magic from the buffer and process the keep alive self.byteStream = self.byteStream[keepAliveMagicLen:] return self.__processKeepAlive(maxBufferSize, blockAfterKeepAlive) # From here it must be a real message! # Process the size and remove the msg length from the bytestream pkgSize = int(self.byteStream[:iSeparatorPosition]) pkgData = self.byteStream[iSeparatorPosition + 1:] readSize = len(pkgData) if readSize >= pkgSize: # If we already have all the data we need data = pkgData[:pkgSize] self.byteStream = pkgData[pkgSize:] else: # If we still need to read stuff pkgMem = BytesIO() pkgMem.write(pkgData) # Receive while there's still data to be received while readSize < pkgSize: retVal = self._read(pkgSize - readSize, skipReadyCheck=True) if not retVal["OK"]: return retVal if not retVal["Value"]: return S_ERROR("Peer closed connection") rcvData = retVal["Value"] readSize += len(rcvData) pkgMem.write(rcvData) if maxBufferSize and readSize > maxBufferSize: return S_ERROR("Read limit exceeded (%s chars)" % maxBufferSize) # Data is here! take it out from the bytestream, dencode and return if readSize == pkgSize: data = pkgMem.getvalue() self.byteStream = b"" else: # readSize > pkgSize: pkgMem.seek(0, 0) data = pkgMem.read(pkgSize) self.byteStream = pkgMem.read() try: data = MixedEncode.decode(data)[0] except Exception as e: return S_ERROR("Could not decode received data: %s" % str(e)) if idleReceive: self.receivedMessages.append(data) return S_OK() return data except Exception as e: gLogger.exception("Network error while receiving data") return S_ERROR("Network error while receiving data: %s" % str(e))