def start(self): self._sender = self._socket.peerAddress() stream = QDataStream(self._socket) if (self._file_size == 0): if (self._socket.bytesAvailable() < getsizeof(int)): return self._file_size = stream.readUInt32() if (self._socket.bytesAvailable() < self._file_size): return self._file_name = stream.readString() line = QByteArray() line = self._socket.readAll() directory = Path(Setup().get_download_dir()) if not (directory.exists() and directory.is_dir()): directory.mkdir() self._receiving_file = QFile(Setup().get_download_dir() + str(self._file_name)) print(Setup().get_download_dir() + str(self._file_name)) if not (self._receiving_file.open(QIODevice.WriteOnly)): print("can't open file") return self._receiving_file.write(line) self._receiving_file.close() self._socket.disconnectFromHost() print("finished") return self._receiving_file
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()
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 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 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()