def run(self): # Try to connect to an incomming tcp socket using its socket descriptor tcpSocket = QTcpSocket() if not tcpSocket.setSocketDescriptor(self.socketDescriptor): FreeCAD.Console.PrintError("Socket not accepted.\n") return # Wait for an incomming message if not tcpSocket.waitForReadyRead(msecs=WAIT_TIME_MS): FreeCAD.Console.PrintError("No request send.\n") return # Make an input data stream instr = QDataStream(tcpSocket) instr.setVersion(QDataStream.Qt_4_0) # Try to read the message size if self.blockSize == 0: if tcpSocket.bytesAvailable() < 2: return self.blockSize = instr.readUInt16() # Check message is sent complete if tcpSocket.bytesAvailable() < self.blockSize: return # Read message and inform about it instr = instr.readString() FreeCAD.Console.PrintLog("CommandServer received> " + str(instr) + "\n") # Try to execute the message string and prepare a response try: exec(str(instr)) except Exception as e: FreeCAD.Console.PrintError("Executing external command failed:" + str(e) + "\n") message = "Command failed - " + str(e) else: FreeCAD.Console.PrintLog("Executing external command succeded!\n") message = COMMAND_EXECUTED_CONFIRMATION_MESSAGE # Prepare the data block to send back and inform about it FreeCAD.Console.PrintLog("CommandServer sending> " + message + " \n") block = QByteArray() outstr = QDataStream(block, QIODevice.WriteOnly) outstr.setVersion(QDataStream.Qt_4_0) outstr.writeUInt16(0) outstr.writeQString(message) outstr.device().seek(0) outstr.writeUInt16(block.size() - 2) # Send the block, disconnect from the socket and terminate the QThread tcpSocket.write(block) tcpSocket.disconnectFromHost() tcpSocket.waitForDisconnected()
class QDataStreamWrite(unittest.TestCase): '''Test case for QDatastream write* functions''' def setUp(self): self.ba = QByteArray() self.read = QDataStream(self.ba, QIODevice.ReadOnly) self.write = QDataStream(self.ba, QIODevice.WriteOnly) def testWriteUInt8(self): '''QDataStream.writeUInt8 (accepting str of size 1)''' x = 0xFF self.write.writeUInt8(x) y = self.read.readUInt8() self.assertEqual(x, y) self.assertRaises(TypeError, self.write.writeUInt8, 'aaaaa') def testWriteInt8(self): '''QDataStream.writeInt8 (accepting str of size 1)''' x = 65 self.write.writeInt8(chr(x)) y = self.read.readInt8() self.assertEqual(x, y) self.assertRaises(TypeError, self.write.writeInt8, 'aaaaa') def testWriteUInt8Int(self): '''QDataStream.writeUInt8 (accepting integer)''' x = 0xFF self.write.writeUInt8(x) y = self.read.readUInt8() self.assertEqual(x, y) def testWriteInt8Int(self): '''QDataStream.writeInt8 (accepting integer)''' x = 65 self.write.writeInt8(x) y = self.read.readInt8() self.assertEqual(x, y) def testWriteUInt16(self): '''QDataStream.writeUInt16''' x = 0x4423 self.write.writeUInt16(x) y = int(self.read.readUInt16()) self.assertEqual(x, y) def testWriteUInt32(self): '''QDataStream.writeUInt32''' x = 0xdeadbeef self.write.writeUInt32(x) y = int(self.read.readUInt32()) self.assertEqual(x, y)
def run(self): self.mutex.lock() serverName = self.hostName serverPort = self.port self.mutex.unlock() while not self.quit: Timeout = 5 * 1000 socket = QTcpSocket() socket.connectToHost(serverName, serverPort) if not socket.waitForConnected(Timeout): self.error.emit(socket.error(), socket.errorString()) return while socket.bytesAvailable() < 2: if not socket.waitForReadyRead(Timeout): self.error.emit(socket.error(), socket.errorString()) return instr = QDataStream(socket) instr.setVersion(QDataStream.Qt_4_0) blockSize = instr.readUInt16() block = QByteArray() outstr = QDataStream(block, QIODevice.WriteOnly) outstr.setVersion(QDataStream.Qt_4_0) while socket.bytesAvailable() < blockSize: if not socket.waitForReadyRead(Timeout): self.error.emit(socket.error(), socket.errorString()) return self.mutex.lock() outstr.writeUInt16(0) outstr.writeQString("Message to Server") outstr.device().seek(0) outstr.writeUInt16(block.size() - 2) socket.write(block) # socket.write(block) fortune = instr.readQString() self.newFortune.emit(fortune) self.cond.wait(self.mutex) serverName = self.hostName serverPort = self.port self.mutex.unlock()
def run(self): tcpSocket = QTcpSocket() if not tcpSocket.setSocketDescriptor(self.socketDescriptor): self.error.emit(tcpSocket.error()) return block = QByteArray() outstr = QDataStream(block, QIODevice.WriteOnly) outstr.setVersion(QDataStream.Qt_4_0) outstr.writeUInt16(0) outstr.writeQString(self.text) outstr.device().seek(0) outstr.writeUInt16(block.size() - 2) tcpSocket.write(block) tcpSocket.disconnectFromHost() tcpSocket.waitForDisconnected()
def sendClientCommand(host, port, cmd, wait_time=WAIT_TIME_MS): # Try to connect to a host server tcpSocket = QTcpSocket() tcpSocket.connectToHost(host, port, QIODevice.ReadWrite) if not tcpSocket.waitForConnected(msecs=wait_time): return CLIENT_ERROR_NO_CONNECTION # Prepare a command message to be sent block = QByteArray() outstr = QDataStream(block, QIODevice.WriteOnly) outstr.setVersion(QDataStream.Qt_4_0) outstr.writeUInt16(0) outstr.writeQString(cmd) outstr.device().seek(0) outstr.writeUInt16(block.size() - 2) tcpSocket.write(block) # Try to send the message if not tcpSocket.waitForBytesWritten(msecs=wait_time): return CLIENT_ERROR_BLOCK_NOT_WRITTEN # Wait for a response from the host server if not tcpSocket.waitForReadyRead(msecs=10000): return CLIENT_ERROR_NO_RESPONSE # Try to read the response instr = QDataStream(tcpSocket) instr.setVersion(QDataStream.Qt_4_0) blockSize = 0 if blockSize == 0: if tcpSocket.bytesAvailable() < 2: return CLIENT_ERROR_RESPONSE_NOT_COMPLETE blockSize = instr.readUInt16() if tcpSocket.bytesAvailable() < blockSize: return CLIENT_ERROR_RESPONSE_NOT_COMPLETE # Wait until the host server terminates the connection tcpSocket.waitForDisconnected() # Return value representing a command execution status if instr.readString() == COMMAND_EXECUTED_CONFIRMATION_MESSAGE: return CLIENT_COMMAND_EXECUTED else: return CLIENT_COMMAND_FAILED
def saveGeometry(self): """ Saves the geometry of this subwindow (see https://bugreports.qt.io/browse/QTBUG-18648) :return: a ByteArray instance """ array = QByteArray() stream = QDataStream(array, QIODevice.WriteOnly) stream.writeUInt32(0x1D9D0CB) stream.writeUInt16(1) stream.writeUInt16(0) frameGeom = self.frameGeometry() stream.writeInt64(frameGeom.x()) stream.writeInt64(frameGeom.y()) stream.writeInt64(frameGeom.width()) stream.writeInt64(frameGeom.height()) normalGeom = self.normalGeometry() stream.writeInt64(normalGeom.x()) stream.writeInt64(normalGeom.y()) stream.writeInt64(normalGeom.width()) stream.writeInt64(normalGeom.height()) stream.writeUInt32(self.windowState() & Qt.WindowMaximized) stream.writeUInt32(self.windowState() & Qt.WindowFullScreen) return array
def sendCommand(self, cmd): # connect a Qt slot to receive and print errors self.tcpSocket.error.connect(self.displayError) # Try to connect to a host server self.tcpSocket.connectToHost(self.host, self.port, QIODevice.ReadWrite) if not self.tcpSocket.waitForConnected(msecs=WAIT_TIME_MS): if "FreeCAD" in sys.modules: FreeCAD.Console.PrintError( "CommandClient.sendCommand error: " + "No connection\n") else: print("CommandClient.sendCommand error: No connection\n") return CLIENT_ERROR_NO_CONNECTION # Prepare a command message to be sent block = QByteArray() outstr = QDataStream(block, QIODevice.WriteOnly) outstr.setVersion(QDataStream.Qt_4_0) outstr.writeUInt16(0) outstr.writeQString(cmd) outstr.device().seek(0) outstr.writeUInt16(block.size() - 2) # Try to send the message if "FreeCAD" in sys.modules: FreeCAD.Console.PrintMessage("CommandClient sending> " + cmd + "\n") else: print("CommandClient sending> " + cmd + "\n") self.tcpSocket.write(block) if not self.tcpSocket.waitForBytesWritten(msecs=WAIT_TIME_MS): if "FreeCAD" in sys.modules: FreeCAD.Console.PrintError( "CommandClient.sendCommand error: " + "Block not written\n") else: print("CommandClient.sendCommand error: Block not written\n") return CLIENT_ERROR_BLOCK_NOT_WRITTEN # Wait for a response from the host server if not self.tcpSocket.waitForReadyRead(msecs=WAIT_TIME_MS): if "FreeCAD" in sys.modules: FreeCAD.Console.PrintError( "CommandClient.sendCommand error: " + "No response received.\n") else: print("CommandClient.sendCommand error: " + "No response received.\n") return CLIENT_ERROR_NO_RESPONSE # Try to read the response instr = QDataStream(self.tcpSocket) instr.setVersion(QDataStream.Qt_4_0) if self.blockSize == 0: if self.tcpSocket.bytesAvailable() < 2: return CLIENT_ERROR_RESPONSE_NOT_COMPLETE self.blockSize = instr.readUInt16() if self.tcpSocket.bytesAvailable() < self.blockSize: return CLIENT_ERROR_RESPONSE_NOT_COMPLETE response = instr.readString() if "FreeCAD" in sys.modules: FreeCAD.Console.PrintMessage("CommandClient received> " + response + "\n") else: print("CommandClient received> " + response + "\n") # Wait until the host server terminates the connection self.tcpSocket.waitForDisconnected() # Reset blockSize to prepare for sending next command self.blockSize = 0 # Return value representing a command execution status if response == COMMAND_EXECUTED_CONFIRMATION_MESSAGE: return CLIENT_COMMAND_EXECUTED else: return CLIENT_COMMAND_FAILED
def testIt(self): a = QByteArray() b = QDataStream(a, QIODevice.WriteOnly) b.writeUInt16(5000) # The __repr__ not suppose to crash anymore self.assertNotEqual(repr(b), None)
def sendClientCommand(host, port, cmd, wait_time=WAIT_TIME_MS): """ Method to be used for sending commands. This method is an alternative to using `CommandClient`. It does not print any logs, just returns a value saying how the execution went. Args: cmd: A str command to be executed. host: A QtHostAddress to the `CommandServer`. port: An int of port at which `CommandServer` is listening. Kwargs: wait_time: An int setting miliseconds to wait for connection or message. Returns: `CLIENT_COMMAND_EXECUTED` if all went great and command was executed. `CLIENT_COMMAND_FAILED` if `cmd` execution failed. `CLIENT_ERROR_RESPONSE_NOT_COMPLETE` if a response received was incomplete. `CLIENT_ERROR_NO_RESPONSE` if there was no response within `WAIT_TIME_MS`. `CLIENT_ERROR_BLOCK_NOT_WRITTEN` if communication failed during sending. `CLIENT_ERROR_NO_CONNECTION` if no connection to a host was established. """ # Try to connect to a host server tcpSocket = QTcpSocket() tcpSocket.connectToHost(host, port, QIODevice.ReadWrite) if not tcpSocket.waitForConnected(msecs=wait_time): return CLIENT_ERROR_NO_CONNECTION # Prepare a command message to be sent block = QByteArray() outstr = QDataStream(block, QIODevice.WriteOnly) outstr.setVersion(QDataStream.Qt_4_0) outstr.writeUInt16(0) outstr.writeQString(cmd) outstr.device().seek(0) outstr.writeUInt16(block.size() - 2) tcpSocket.write(block) # Try to send the message if not tcpSocket.waitForBytesWritten(msecs=wait_time): return CLIENT_ERROR_BLOCK_NOT_WRITTEN # Wait for a response from the host server if not tcpSocket.waitForReadyRead(msecs=10000): return CLIENT_ERROR_NO_RESPONSE # Try to read the response instr = QDataStream(tcpSocket) instr.setVersion(QDataStream.Qt_4_0) blockSize = 0 if blockSize == 0: if tcpSocket.bytesAvailable() < 2: return CLIENT_ERROR_RESPONSE_NOT_COMPLETE blockSize = instr.readUInt16() if tcpSocket.bytesAvailable() < blockSize: return CLIENT_ERROR_RESPONSE_NOT_COMPLETE # Wait until the host server terminates the connection tcpSocket.waitForDisconnected() # Return value representing a command execution status if instr.readString() == COMMAND_EXECUTED_CONFIRMATION_MESSAGE: return CLIENT_COMMAND_EXECUTED else: return CLIENT_COMMAND_FAILED
def sendCommand(self, cmd): """ Method used to send commands from client to `CommandServer`. This method tries to connect to a specified host `CommandServer` via `tcpSocket`. If connection was successfull, the command `cmd` is sent. Then the response is expected. If the response is equal to COMMAND_EXECUTED_CONFIRMATION_MESSAGE, then the execution was successfull. The progress and result of `sendCommand` can be obtained from printed logs and return value. Args: cmd: A str command to be executed. Returns: `CLIENT_COMMAND_EXECUTED` if all went great and command was executed. `CLIENT_COMMAND_FAILED` if `cmd` execution failed. `CLIENT_ERROR_RESPONSE_NOT_COMPLETE` if a response received was incomplete. `CLIENT_ERROR_NO_RESPONSE` if there was no response within `WAIT_TIME_MS`. `CLIENT_ERROR_BLOCK_NOT_WRITTEN` if communication failed during sending. `CLIENT_ERROR_NO_CONNECTION` if no connection to a host was established. """ # connect a Qt slot to receive and print errors self.tcpSocket.error.connect(self.displayError) # Try to connect to a host server self.tcpSocket.connectToHost(self.host, self.port, QIODevice.ReadWrite) if not self.tcpSocket.waitForConnected(msecs=WAIT_TIME_MS): if "FreeCAD" in sys.modules: FreeCAD.Console.PrintError( "CommandClient.sendCommand error: " + "No connection\n") else: print("CommandClient.sendCommand error: No connection\n") return CLIENT_ERROR_NO_CONNECTION # Prepare a command message to be sent block = QByteArray() outstr = QDataStream(block, QIODevice.WriteOnly) outstr.setVersion(QDataStream.Qt_4_0) outstr.writeUInt16(0) outstr.writeQString(cmd) outstr.device().seek(0) outstr.writeUInt16(block.size() - 2) # Try to send the message if "FreeCAD" in sys.modules: FreeCAD.Console.PrintMessage("CommandClient sending> " + cmd + "\n") else: print("CommandClient sending> " + cmd + "\n") self.tcpSocket.write(block) if not self.tcpSocket.waitForBytesWritten(msecs=WAIT_TIME_MS): if "FreeCAD" in sys.modules: FreeCAD.Console.PrintError( "CommandClient.sendCommand error: " + "Block not written\n") else: print("CommandClient.sendCommand error: Block not written\n") return CLIENT_ERROR_BLOCK_NOT_WRITTEN # Wait for a response from the host server if not self.tcpSocket.waitForReadyRead(msecs=WAIT_TIME_MS): if "FreeCAD" in sys.modules: FreeCAD.Console.PrintError( "CommandClient.sendCommand error: " + "No response received.\n") else: print("CommandClient.sendCommand error: " + "No response received.\n") return CLIENT_ERROR_NO_RESPONSE # Try to read the response instr = QDataStream(self.tcpSocket) instr.setVersion(QDataStream.Qt_4_0) if self.blockSize == 0: if self.tcpSocket.bytesAvailable() < 2: return CLIENT_ERROR_RESPONSE_NOT_COMPLETE self.blockSize = instr.readUInt16() if self.tcpSocket.bytesAvailable() < self.blockSize: return CLIENT_ERROR_RESPONSE_NOT_COMPLETE response = instr.readString() if "FreeCAD" in sys.modules: FreeCAD.Console.PrintMessage("CommandClient received> " + response + "\n") else: print("CommandClient received> " + response + "\n") # Wait until the host server terminates the connection self.tcpSocket.waitForDisconnected() # Reset blockSize to prepare for sending next command self.blockSize = 0 # Return value representing a command execution status if response == COMMAND_EXECUTED_CONFIRMATION_MESSAGE: return CLIENT_COMMAND_EXECUTED else: return CLIENT_COMMAND_FAILED
def run(self): """ Thread's functionality method. The starting point for the thread. After calling start(), the newly created thread calls this function. This function then tries to make QTcpSocket. It waits `WAIT_TIME_MS` for an incomming message. If message is received it checks its a whole message using blockSize sent in the first word as an UINT16 number. If a whole message is received, the thread tries to execute the message string and sends back an appropriate response. The response is *Command failed - "error string"* if the execution failed, or *Commmand executed successfully* otherwise. Then the thread is terminated. """ # Try to connect to an incomming tcp socket using its socket descriptor tcpSocket = QTcpSocket() if not tcpSocket.setSocketDescriptor(self.socketDescriptor): FreeCAD.Console.PrintError("Socket not accepted.\n") return # Wait for an incomming message if not tcpSocket.waitForReadyRead(msecs=WAIT_TIME_MS): FreeCAD.Console.PrintError("No request send.\n") return # Make an input data stream instr = QDataStream(tcpSocket) instr.setVersion(QDataStream.Qt_4_0) # Try to read the message size if self.blockSize == 0: if tcpSocket.bytesAvailable() < 2: return self.blockSize = instr.readUInt16() # Check message is sent complete if tcpSocket.bytesAvailable() < self.blockSize: return # Read message and inform about it instr = instr.readString() FreeCAD.Console.PrintLog("CommandServer received> " + str(instr) + "\n") # Try to execute the message string and prepare a response try: exec(str(instr)) except Exception as e: FreeCAD.Console.PrintError("Executing external command failed:" + str(e) + "\n") message = "Command failed - " + str(e) else: FreeCAD.Console.PrintLog("Executing external command succeded!\n") message = COMMAND_EXECUTED_CONFIRMATION_MESSAGE # Prepare the data block to send back and inform about it FreeCAD.Console.PrintLog("CommandServer sending> " + message + " \n") block = QByteArray() outstr = QDataStream(block, QIODevice.WriteOnly) outstr.setVersion(QDataStream.Qt_4_0) outstr.writeUInt16(0) outstr.writeQString(message) outstr.device().seek(0) outstr.writeUInt16(block.size() - 2) # Send the block, disconnect from the socket and terminate the QThread tcpSocket.write(block) tcpSocket.disconnectFromHost() tcpSocket.waitForDisconnected()