Пример #1
0
    def run(self):
        # Try to connect to an incoming tcp socket using its socket descriptor
        tcpSocket = QTcpSocket()
        if not tcpSocket.setSocketDescriptor(self.socketDescriptor):
            FreeCAD.Console.PrintError("Socket not accepted.\n")
            return
        FreeCAD.Console.PrintLog("Socket accepted.\n")

        # Wait for an incoming 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:
                FreeCAD.Console.PrintError("Received message "
                                           + "has too few bytes.\n")
                return
            self.blockSize = instr.readUInt16()

        # Check message is sent complete
        if tcpSocket.bytesAvailable() < self.blockSize:
            FreeCAD.Console.PrintError("Received message has less bytes "
                                       + "then it's supposed to.\n")
            return

        # Read message and inform about it
        cmd = instr.readRawData(self.blockSize).decode("UTF-8")
        FreeCAD.Console.PrintLog("CommandServer received> "
                                 + cmd + "\n")

        # Try to execute the message string and prepare  a response
        try:
            exec(cmd)
        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 succeeded!\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(
                len(message.encode("UTF-8")).to_bytes(2, byteorder='big')
                + message.encode("UTF-8"))
        outstr = QDataStream(block, QIODevice.WriteOnly)
        outstr.setVersion(QDataStream.Qt_4_0)

        # Send the block, disconnect from the socket and terminate the QThread
        tcpSocket.write(block)
        tcpSocket.disconnectFromHost()
        tcpSocket.waitForDisconnected()
Пример #2
0
    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 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()
Пример #4
0
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
Пример #5
0
    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()

            while socket.bytesAvailable() < blockSize:
                if not socket.waitForReadyRead(Timeout):
                    self.error.emit(socket.error(), socket.errorString())
                    return

            self.mutex.lock()
            fortune = instr.readQString()
            self.newFortune.emit(fortune)

            self.cond.wait(self.mutex)
            serverName = self.hostName
            serverPort = self.port
            self.mutex.unlock()
    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()

            while socket.bytesAvailable() < blockSize:
                if not socket.waitForReadyRead(Timeout):
                    self.error.emit(socket.error(), socket.errorString())
                    return

            self.mutex.lock()
            fortune = instr.readQString()
            self.newFortune.emit(fortune)

            self.cond.wait(self.mutex)
            serverName = self.hostName
            serverPort = self.port
            self.mutex.unlock()
Пример #7
0
class CommandClient:

    ## @property		host
    # A QtHostAddress to the `CommandServer`.

    ## @property		port
    # An int of port at which `CommandServer` is listening.

    ## @property		tcpSocket
    # A QTcpSocket used to contact `CommandSErver`

    ## @property		blockSize
    # An int representing size of incomming tcp message.

    ## @brief Initialization method for CommandClient.
    #
    #A class instance is created and its attributes are initialized.
    #
    #
    # @param		host	A QtHostAddress to the `CommandServer`.
    # @param		port	An int of port at which `CommandServer` is listening.
    #

    def __init__(self, host, port):
        self.host = host
        self.port = port
        self.tcpSocket = QTcpSocket()
        self.blockSize = 0

    ## @brief 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.
    #
    #
    # @param		cmd	A str command to be executed.
    #
    # @return
    #    `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.
    #

    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

    ## @brief `Qt`'s slot method to print out received `tcpSocket`'s error.
    #
    #QAbstractSocket.RemoteHostClosedError is not printed, because it occurs
    #naturaly when the `tcpSocket` closes after a transaction is over. Except that
    #all errors are printed.
    #
    #
    # @param		socketError	A QAbstractSocket::SocketError enum describing occured error.
    #

    def displayError(self, socketError):
        if socketError != QAbstractSocket.RemoteHostClosedError:
            if "FreeCAD" in sys.modules:
                FreeCAD.Console.PrintError(
                    "CommandClient error occurred> %s." %
                    self.tcpSocket.errorString() + "\n")
            else:
                print("CommandClient error occurred> %s." %
                      self.tcpSocket.errorString() + "\n")
Пример #8
0
class CrossingNetwork(QObject):
    # Změna stavu; signál pro stavový řádek
    stateChanged = Signal(str)

    def __init__(self, model, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.model = model

        # Inicializace socketu
        self.socket = QTcpSocket(self)
        self.socket.readyRead.connect(self.read)
        self.socket.stateChanged.connect(self.socketStateChanged)

        # Příprava pro čtení dat
        self.readBuffer = QByteArray()
        self.textCodec = QTextCodec.codecForName("UTF-8")

    @Slot()
    def socketConnect(self):
        # Nejdřív se odpoj, pokud už spojení běží
        self.socket.abort()

        # A znovu se připoj
        self.socket.connectToHost(
            "ksp.mff.cuni.cz", 48888)

    @Slot()
    def socketDisconnect(self):
        # Odpoj se
        self.socket.disconnectFromHost()

        # Vyprázdni model
        self.model.flush()

    @Slot(SocketState)
    def socketStateChanged(self, state):
        if state == SocketState.ConnectedState:
            # Připojeni? Pozdravíme server.
            self.socket.write(self.textCodec.fromUnicode("HELLO\n"))

        # A informujeme připojené posluchače o změně stavu
        self.stateChanged.emit(str(state).split(".")[-1].split("State")[0])

    def read(self):
        # Přečteme všechno, co jsme dostali
        while self.socket.bytesAvailable() > 0:
            self.readBuffer += \
                self.socket.read(128)

        # Rozdělíme na řádky
        lines = self.readBuffer.split("\n")

        # Zbytek uložíme na příště
        self.readBuffer = lines.pop()

        # Zpracujeme řádky, které dorazily
        for l in lines:
            stripped = self.textCodec.toUnicode(l.data()).rstrip()
            args = stripped.split(" ")
            travellerType = args.pop(0)
            argmap = dict(map(
                lambda x: x.split("="), args))

            if travellerType == "CAR":
                self.addTraveller(Car(**argmap))
            elif travellerType == "PEDESTRIAN":
                self.addTraveller(
                    Pedestrian(**argmap))

    def addTraveller(self, traveller):
        # Uložíme si cestovatele
        self.model.add(traveller)

        # Nechť cestovatel vstoupí do oblasti
        traveller.start(self)

    def sendBack(self, traveller):
        # Vrátíme cestovatele serveru
        text = str(traveller) + "\n"
        self.socket.write(self.textCodec.fromUnicode(text))

        self.model.remove(traveller)
Пример #9
0
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.

To send a command using this method do:
     sendClientCommand("127.0.0.1",54333,
                       "FreeCAD.Console.PrintWarning('Hello World\\n')")

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 milliseconds 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(
        len(cmd.encode("UTF-8")).to_bytes(2, byteorder='big') +
        cmd.encode("UTF-8"))
    outstr = QDataStream(block, QIODevice.WriteOnly)
    outstr.setVersion(QDataStream.Qt_4_0)
    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=wait_time):
        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.readRawData(blockSize).decode("UTF-8") \
            == COMMAND_EXECUTED_CONFIRMATION_MESSAGE:
        return CLIENT_COMMAND_EXECUTED
    else:
        return CLIENT_COMMAND_FAILED
Пример #10
0
class CommandClient:
    """
Class to be used for sending commands.

This class can be used in FreeCAD's or regular python console to send commands
to a `CommandServer` using `sendCommand()`. The class prints logs as it moves
along.

Attributes:
    host: A QtHostAddress to the `CommandServer`.
    port: An int of port at which `CommandServer` is listening.
    tcpSocket: A QTcpSocket used to contact `CommandSErver`
    blockSize: An int representing size of incoming tcp message.

To send a commands do:
    client = CommandClient("127.0.0.1",54321)
    client.sendCommand('FreeCAD.Console.PrintError("Hello World\\n")\n')
    client.sendCommand('FreeCAD.Console.PrintError("Bye Bye\\n")\n')
    """
    def __init__(self, host, port):
        """
Initialization method for CommandClient.

A class instance is created and its attributes are initialized.

Args:
    host: A QtHostAddress to the `CommandServer`.
    port: An int of port at which `CommandServer` is listening.
        """
        self.host = host
        self.port = port
        self.tcpSocket = QTcpSocket()
        self.blockSize = 0

    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 successful, the command `cmd` is sent.
Then the response is expected. If the response is equal to
COMMAND_EXECUTED_CONFIRMATION_MESSAGE, then the execution was successful.
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(
            len(cmd.encode("UTF-8")).to_bytes(2, byteorder='big') +
            cmd.encode("UTF-8"))
        outstr = QDataStream(block, QIODevice.WriteOnly)
        outstr.setVersion(QDataStream.Qt_4_0)

        # 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.readRawData(self.blockSize).decode("UTF-8")
        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 displayError(self, socketError):
        """
`Qt`'s slot method to print out received `tcpSocket`'s error.

QAbstractSocket.RemoteHostClosedError is not printed, because it occurs
naturally when the `tcpSocket` closes after a transaction is over. Except that
all errors are printed.

Args:
    socketError: A QAbstractSocket::SocketError enum describing occurred error.
        """
        if socketError != QAbstractSocket.RemoteHostClosedError:
            if "FreeCAD" in sys.modules:
                FreeCAD.Console.PrintError(
                    "CommandClient error occurred> %s." %
                    self.tcpSocket.errorString() + "\n")
            else:
                print("CommandClient error occurred> %s." %
                      self.tcpSocket.errorString() + "\n")
Пример #11
0
    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 incoming 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 *Command
executed successfully* otherwise. Then the thread is terminated.
        """
        # Try to connect to an incoming tcp socket using its socket descriptor
        tcpSocket = QTcpSocket()
        if not tcpSocket.setSocketDescriptor(self.socketDescriptor):
            FreeCAD.Console.PrintError("Socket not accepted.\n")
            return
        FreeCAD.Console.PrintLog("Socket accepted.\n")

        # Wait for an incoming 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:
                FreeCAD.Console.PrintError("Received message " +
                                           "has too few bytes.\n")
                return
            self.blockSize = instr.readUInt16()

        # Check message is sent complete
        if tcpSocket.bytesAvailable() < self.blockSize:
            FreeCAD.Console.PrintError("Received message has less bytes " +
                                       "then it's supposed to.\n")
            return

        # Read message and inform about it
        cmd = instr.readRawData(self.blockSize).decode("UTF-8")
        FreeCAD.Console.PrintLog("CommandServer received> " + cmd + "\n")

        # Try to execute the message string and prepare  a response
        try:
            exec(cmd)
        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 succeeded!\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(
            len(message.encode("UTF-8")).to_bytes(2, byteorder='big') +
            message.encode("UTF-8"))
        outstr = QDataStream(block, QIODevice.WriteOnly)
        outstr.setVersion(QDataStream.Qt_4_0)

        # Send the block, disconnect from the socket and terminate the QThread
        tcpSocket.write(block)
        tcpSocket.disconnectFromHost()
        tcpSocket.waitForDisconnected()