示例#1
0
 def handleRecv(self):
     ip = QHostAddress()
     buf = bytes()
     buf, ip, port = self.udpSocket.readDatagram(1024)
     ip = ip.toString()
     message = buf.decode()
     self.ui.textEdit.setText('{Ip},{Port}:{Message}'.format(Ip=ip, Port=port, Message=message))
示例#2
0
    def sessionOpened(self):
        if self.networkSession is not None:
            config = self.networkSession.configuration()

            if config.type() == QNetworkConfiguration.UserChoice:
                id = self.networkSession.sessionProperty('UserChoiceConfiguration')
            else:
                id = config.identifier()

            settings = QSettings(QSettings.UserScope, 'QtProject')
            settings.beginGroup('QtNetwork')
            settings.setValue('DefaultNetworkConfiguration', id)
            settings.endGroup();

        self.tcpServer = QTcpServer(self)
        if not self.tcpServer.listen():
            QMessageBox.critical(self, "Fortune Server",
                    "Unable to start the server: %s." % self.tcpServer.errorString())
            self.close()
            return

        for ipAddress in QNetworkInterface.allAddresses():
            if ipAddress != QHostAddress.LocalHost and ipAddress.toIPv4Address() != 0:
                break
        else:
            ipAddress = QHostAddress(QHostAddress.LocalHost)

        ipAddress = ipAddress.toString()

        self.statusLabel.setText("The server is running on\n\nIP: %s\nport %d\n\n"
                "Run the Fortune Client example now." % (ipAddress, self.tcpServer.serverPort()))
def getIPAddress():
    for ipAddress in QNetworkInterface.allAddresses():
        if ipAddress != QHostAddress.LocalHost and ipAddress.toIPv4Address(
        ) != 0:
            break
    else:
        ipAddress = QHostAddress(QHostAddress.LocalHost)
    return ipAddress.toString()
    def __init__(self, parent=None):
        super(BlockingClient, self).__init__(parent)

        self.thread = FortuneThread()
        self.currentFortune = ""

        hostLabel = QLabel("&Server name:")
        portLabel = QLabel("S&erver port:")

        for ipAddress in QNetworkInterface.allAddresses():
            if ipAddress != QHostAddress.LocalHost and ipAddress.toIPv4Address(
            ) != 0:
                break
        else:
            ipAddress = QHostAddress(QHostAddress.LocalHost)

        ipAddress = ipAddress.toString()

        self.hostLineEdit = QLineEdit(ipAddress)
        self.portLineEdit = QLineEdit()
        self.portLineEdit.setValidator(QIntValidator(1, 65535, self))

        hostLabel.setBuddy(self.hostLineEdit)
        portLabel.setBuddy(self.portLineEdit)

        self.statusLabel = QLabel(
            "This example requires that you run the Fortune Server example as well."
        )
        self.statusLabel.setWordWrap(True)

        self.getFortuneButton = QPushButton("Get Fortune")
        self.getFortuneButton.setDefault(True)
        self.getFortuneButton.setEnabled(False)

        quitButton = QPushButton("Quit")

        buttonBox = QDialogButtonBox()
        buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole)
        buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole)

        self.getFortuneButton.clicked.connect(self.requestNewFortune)
        quitButton.clicked.connect(self.close)
        self.hostLineEdit.textChanged.connect(self.enableGetFortuneButton)
        self.portLineEdit.textChanged.connect(self.enableGetFortuneButton)
        self.thread.newFortune.connect(self.showFortune)
        self.thread.error.connect(self.displayError)

        mainLayout = QGridLayout()
        mainLayout.addWidget(hostLabel, 0, 0)
        mainLayout.addWidget(self.hostLineEdit, 0, 1)
        mainLayout.addWidget(portLabel, 1, 0)
        mainLayout.addWidget(self.portLineEdit, 1, 1)
        mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2)
        mainLayout.addWidget(buttonBox, 3, 0, 1, 2)
        self.setLayout(mainLayout)

        self.setWindowTitle("Blocking Fortune Client")
        self.portLineEdit.setFocus()
    def __init__(self, parent=None):
        super(BlockingClient, self).__init__(parent)

        self.thread = FortuneThread()
        self.currentFortune = ''

        hostLabel = QLabel("&Server name:")
        portLabel = QLabel("S&erver port:")

        for ipAddress in QNetworkInterface.allAddresses():
            if ipAddress != QHostAddress.LocalHost and ipAddress.toIPv4Address() != 0:
                break
        else:
            ipAddress = QHostAddress(QHostAddress.LocalHost)

        ipAddress = ipAddress.toString()

        self.hostLineEdit = QLineEdit(ipAddress)
        self.portLineEdit = QLineEdit()
        self.portLineEdit.setValidator(QIntValidator(1, 65535, self))

        hostLabel.setBuddy(self.hostLineEdit)
        portLabel.setBuddy(self.portLineEdit)

        self.statusLabel = QLabel(
                "This example requires that you run the Fortune Server example as well.")
        self.statusLabel.setWordWrap(True)

        self.getFortuneButton = QPushButton("Get Fortune")
        self.getFortuneButton.setDefault(True)
        self.getFortuneButton.setEnabled(False)

        quitButton = QPushButton("Quit")

        buttonBox = QDialogButtonBox()
        buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole)
        buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole)

        self.getFortuneButton.clicked.connect(self.requestNewFortune)
        quitButton.clicked.connect(self.close)
        self.hostLineEdit.textChanged.connect(self.enableGetFortuneButton)
        self.portLineEdit.textChanged.connect(self.enableGetFortuneButton)
        self.thread.newFortune.connect(self.showFortune)
        self.thread.error.connect(self.displayError)

        mainLayout = QGridLayout()
        mainLayout.addWidget(hostLabel, 0, 0)
        mainLayout.addWidget(self.hostLineEdit, 0, 1)
        mainLayout.addWidget(portLabel, 1, 0)
        mainLayout.addWidget(self.portLineEdit, 1, 1)
        mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2)
        mainLayout.addWidget(buttonBox, 3, 0, 1, 2)
        self.setLayout(mainLayout)

        self.setWindowTitle("Blocking Fortune Client")
        self.portLineEdit.setFocus()
    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)

        self.server = FortuneServer()

        statusLabel = QLabel()
        statusLabel.setWordWrap(True)
        quitButton = QPushButton("Quit")
        quitButton.setAutoDefault(False)

        if not self.server.listen():
            QMessageBox.critical(
                self,
                "Threaded Fortune Server",
                "Unable to start the server: %s." % self.server.errorString(),
            )
            self.close()
            return

        for ipAddress in QNetworkInterface.allAddresses():
            if ipAddress != QHostAddress.LocalHost and ipAddress.toIPv4Address() != 0:
                break
        else:
            ipAddress = QHostAddress(QHostAddress.LocalHost)

        ipAddress = ipAddress.toString()

        statusLabel.setText(
            "The server is running on\n\nIP: %s\nport: %d\n\n"
            "Run the Fortune Client example now."
            % (ipAddress, self.server.serverPort())
        )

        quitButton.clicked.connect(self.close)

        buttonLayout = QHBoxLayout()
        buttonLayout.addStretch(1)
        buttonLayout.addWidget(quitButton)
        buttonLayout.addStretch(1)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(statusLabel)
        mainLayout.addLayout(buttonLayout)
        self.setLayout(mainLayout)

        self.setWindowTitle("Threaded Fortune Server")
    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)

        self.server = FortuneServer()

        statusLabel = QLabel()
        statusLabel.setWordWrap(True)
        quitButton = QPushButton("Quit")
        quitButton.setAutoDefault(False)

        if not self.server.listen():
            QMessageBox.critical(self, "Threaded Fortune Server",
                    "Unable to start the server: %s." % self.server.errorString())
            self.close()
            return

        for ipAddress in QNetworkInterface.allAddresses():
            if ipAddress != QHostAddress.LocalHost and ipAddress.toIPv4Address() != 0:
                break
        else:
            ipAddress = QHostAddress(QHostAddress.LocalHost)

        ipAddress = ipAddress.toString()

        statusLabel.setText("The server is running on\n\nIP: %s\nport: %d\n\n"
                "Run the Fortune Client example now." % (ipAddress, self.server.serverPort()))

        quitButton.clicked.connect(self.close)

        buttonLayout = QHBoxLayout()
        buttonLayout.addStretch(1)
        buttonLayout.addWidget(quitButton)
        buttonLayout.addStretch(1)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(statusLabel)
        mainLayout.addLayout(buttonLayout)
        self.setLayout(mainLayout)

        self.setWindowTitle("Threaded Fortune Server")
示例#8
0
 def listen(self, host=None, port=3000):
     """Method making the server listening to a given address."""
     # If no address was specified: trying to give the best one
     if host is None:
         for ip in self.get_available_ips():
             if ip != QHostAddress.LocalHost and ip.toIPv4Address():
                 host = ip
         if host is None:  # No suitable address was found
             host = QHostAddress.LocalHost
     # The address was given as string
     if type(host) == str:
         host = QHostAddress(host)
     # For printing...
     address = "{}:{}".format(host.toString(), port)
     # Launching server
     if not self.__tcpServer.listen(host, port):
         self.__tcpServer.close()
         print("Unable to listen on address '{}': {}.".format(
             address, self.__tcpServer.errorString()))
         raise ConnectionError(self.__tcpServer.errorString())
     else:
         print("Server is listening on address '{}'.".format(address))
         self.listening.emit((host, port))
    def sessionOpened(self):
        if self.networkSession is not None:
            config = self.networkSession.configuration()

            if config.type() == QNetworkConfiguration.UserChoice:
                id = self.networkSession.sessionProperty(
                    'UserChoiceConfiguration')
            else:
                id = config.identifier()

            settings = QSettings(QSettings.UserScope, 'QtProject')
            settings.beginGroup('QtNetwork')
            settings.setValue('DefaultNetworkConfiguration', id)
            settings.endGroup()

        self.tcpServer = QTcpServer(self)
        if not self.tcpServer.listen():
            QMessageBox.critical(
                self, "Fortune Server", "Unable to start the server: %s." %
                self.tcpServer.errorString())
            self.close()
            return

        for ipAddress in QNetworkInterface.allAddresses():
            if ipAddress != QHostAddress.LocalHost and ipAddress.toIPv4Address(
            ) != 0:
                break
        else:
            ipAddress = QHostAddress(QHostAddress.LocalHost)

        ipAddress = ipAddress.toString()

        self.statusLabel.setText(
            "The server is running on\n\nIP: %s\nport %d\n\n"
            "Run the Fortune Client example now." %
            (ipAddress, self.tcpServer.serverPort()))
示例#10
0
class TcpClient(QWidget):
    def __init__(self):
        super().__init__()
        self.isOnline = False
        self.port = 8888
        self.serverIP = QHostAddress('127.0.0.1')
        self.initUI()

    def initUI(self):
        self.ui = ui_tcpClient.Ui_Form()
        self.ui.setupUi(self)
        self.ui.sendBtn.setEnabled(False)
        self.ui.portLineEdit.setText(str(self.port))
        self.ui.serverIPLineEdit.setText(self.serverIP.toString())

        self.ui.enterBtn.clicked.connect(self.slotEnterOrLeave)
        self.ui.sendBtn.clicked.connect(self.slotSend)
        self.ui.sendLineEdit.returnPressed.connect(self.slotSend)

        self.show()

    def slotEnterOrLeave(self):
        if not self.isOnline:
            if not self.validate(): return
            self.enterRoom()
        else:
            self.leaveRoom()

    def validate(self):
        if self.ui.userNameLineEdit.text() == '':
            QMessageBox().information(self, 'ERROR', 'User Name Error!')
            return False
        self.userName = self.ui.userNameLineEdit.text()

        if not self.serverIP.setAddress(
                self.ui.serverIPLineEdit.text()):  # 判断给定的IP是否能够被正确解析
            QMessageBox().information(self, 'ERROR', 'Server IP Error!')
            return False

        if not (0 <= int(self.ui.portLineEdit.text()) <= 65535):
            QMessageBox().information(self, 'ERROR', 'Server Port Error!')
            return False
        self.port = int(self.ui.portLineEdit.text())
        return True

    def enterRoom(self):
        self.tcpSocket = QTcpSocket(self)
        self.tcpSocket.connectToHost(self.serverIP, self.port)

        self.tcpSocket.connected.connect(self.slotConnected)
        self.tcpSocket.readyRead.connect(self.slotDataReceived)
        self.tcpSocket.disconnected.connect(self.slotDisconnected)
        self.tcpSocket.error.connect(self.slotErrorOccured)

    def leaveRoom(self):
        sendData = '[-] ' + self.userName + ': Leave Chat Room'
        self.tcpSocket.write(bytes(sendData, encoding='utf-8'))
        self.tcpSocket.disconnectFromHost()

    def slotSend(self):
        if self.ui.sendLineEdit.text() == '':
            return
        sendData = self.userName + ': ' + self.ui.sendLineEdit.text()
        self.tcpSocket.write(bytes(sendData, encoding='utf-8'))
        self.ui.sendLineEdit.clear()

    def slotConnected(self):
        self.ui.sendBtn.setEnabled(True)
        self.ui.userNameLineEdit.setEnabled(False)
        self.ui.serverIPLineEdit.setEnabled(False)
        self.ui.portLineEdit.setEnabled(False)
        self.ui.enterBtn.setText('Leave Chat Room')
        self.isOnline = True

        sendData = '[+] ' + self.userName + ': Enter Chat Room'
        self.tcpSocket.write(bytes(sendData, encoding='utf-8'))

    def slotDataReceived(self):
        recvData = ''
        while self.tcpSocket.bytesAvailable() > 0:
            recvData = self.tcpSocket.read(self.tcpSocket.bytesAvailable())
        self.ui.contentListWidget.addItem(str(recvData, encoding='utf-8'))
        self.ui.contentListWidget.scrollToBottom()  # 滚动到最后一行

    def slotDisconnected(self):
        self.ui.sendBtn.setEnabled(False)
        self.ui.userNameLineEdit.setEnabled(True)
        self.ui.serverIPLineEdit.setEnabled(True)
        self.ui.portLineEdit.setEnabled(True)
        self.ui.enterBtn.setText('Enter Chat Room')
        self.isOnline = False

    def closeEvent(self, event):
        if self.isOnline:
            msg = 'Are you sure to leave the chat room ?'
            reply = QMessageBox().warning(self, 'Quit', msg,
                                          QMessageBox.Yes | QMessageBox.No,
                                          QMessageBox.No)
            if reply == QMessageBox.Yes:
                self.leaveRoom()
                event.accept()
            else:
                event.ignore()
        else:
            event.accept()

    def slotErrorOccured(self, socketError):
        if socketError == 0:
            msg = '[*] ConnectionRefusedError: The connection was refused by the peer (or timed out).'
            self.ui.contentListWidget.addItem(msg)
        elif socketError == 1:
            msg = '[*] RemoteHostClosedError: The remote host closed the connection.'
            self.ui.contentListWidget.addItem(msg)
示例#11
0
class LogServer(QTcpServer):
    def __init__(self, main_window, on_connection, log, stop_signal):
        super().__init__()
        self.log = log.getChild('TCP')

        self.log.info('Initializing')

        self.main_window = main_window
        self.on_connection = on_connection
        self.stop_signal = stop_signal

        self.host, self.port = CONFIG.listen_address
        self.host = QHostAddress(self.host)
        self.benchmark = CONFIG['benchmark']

        self.threads = []
        self.connections = 0

    def start(self):
        self.log.info('Starting the server')
        if self.benchmark:
            self.log.debug('Starting a benchmark connection')
            new_conn = BenchmarkConnection(self, None, "benchmark",
                                           self.stop_signal, self.log)
            self.on_connection(new_conn, "benchmark")
            self.threads.append(new_conn)
            new_conn.start()

        result = self.listen(self.host, self.port)
        if not result:
            err_string = self.errorString()
            show_critical_dialog(self.main_window,
                                 'Error while starting the server', err_string)
        else:
            address = "{}:{}".format(self.host.toString(), self.port)
            self.main_window.set_status(
                'Server is listening on {}...'.format(address))

    def incomingConnection(self, socketDescriptor):
        self.connections += 1
        name = 'Logger {}'.format(self.connections)
        self.log.info('New connection: "{}"'.format(name))
        new_conn = LogConnection(self, socketDescriptor, name,
                                 self.stop_signal, self.log)

        self.on_connection(new_conn, name)
        new_conn.finished.connect(new_conn.deleteLater)
        new_conn.connection_finished.connect(self.cleanup_connection)
        new_conn.start()
        self.threads.append(new_conn)

    def close_server(self, wait=True):
        self.log.debug('Closing the server')
        self.main_window.set_status('Stopping the server...')
        self.close()
        if wait:
            self.wait_connections_stopped()
        self.main_window.set_status('Server has stopped')

    def wait_connections_stopped(self):
        self.log.debug('Waiting for {} connections threads to stop'.format(
            len(self.threads)))
        to_wait = self.threads.copy(
        )  # to protect against changes during iteration
        for thread in to_wait:
            try:
                if not thread.wait(1000):
                    self.log.error(
                        'Thread "{}" didn\'t stop in time, terminating'.format(
                            thread))
                    thread.terminate()
                    self.log.error('Thread "{}" terminated'.format(thread))
            except RuntimeError:  # happens when thread has been deleted before we got to it
                self.log.debug(
                    'Thread {} has been deleted already'.format(thread))
        self.log.debug('All connections stopped')

    def cleanup_connection(self, connection):
        try:
            self.threads.remove(connection)
        except Exception as e:
            self.log.error(
                'Double delete on connection: {}'.format(connection),
                exc_info=True)
示例#12
0
class TcpServer(QWidget):
    def __init__(self):
        super().__init__()
        self.isUp = False
        self.port = 8888
        self.serverIP = QHostAddress('127.0.0.1')
        self.tcpClientList = []
        self.initUi()

    def initUi(self):
        self.ui = ui_tcpServer.Ui_Form()
        self.ui.setupUi(self)
        self.ui.splitter.setStretchFactor(1,1)
        self.ui.portLineEdit.setText(str(self.port))
        self.ui.serverIPLineEdit.setText(self.serverIP.toString())
        self.ui.openBtn.clicked.connect(self.slotOpenOrClose)
        self.show()

    def validate(self):
        if not self.serverIP.setAddress(self.ui.serverIPLineEdit.text()):  # 判断给定的IP是否能够被正确解析
            QMessageBox().information(self, 'ERROR', 'Server IP Error!')
            return False

        if not (0 <= int(self.ui.portLineEdit.text()) <= 65535):
            QMessageBox().information(self, 'ERROR', 'Server Port Error!')
            return False
        self.port = int(self.ui.portLineEdit.text())
        return True

    def slotOpenOrClose(self):
        if not self.isUp:
            if not self.validate(): return
            self.openRoom()
        else:
            self.closeRoom()

    def openRoom(self):
        self.ui.openBtn.setText('Close Chat Room')
        self.isUp = True
        self.ui.serverIPLineEdit.setEnabled(False)
        self.ui.portLineEdit.setEnabled(False)

        self.tcpServer = QTcpServer()
        self.tcpServer.listen(self.serverIP, self.port)
        msg = '[*] Server is listening on {}:{} ........'.format(self.serverIP.toString(), self.port)
        self.ui.contentListWidget.addItem(msg)
        self.tcpServer.newConnection.connect(self.addClient2List)

    def closeRoom(self):
        del (self.tcpServer)
        self.tcpClientList = []
        self.ui.userListWidget.clear()
        self.isUp = False
        self.ui.serverIPLineEdit.setEnabled(True)
        self.ui.portLineEdit.setEnabled(True)
        self.ui.openBtn.setText('Open Chat Room')
        msg = '[*] Chat Room is closed........'
        self.ui.contentListWidget.addItem(msg)

    def addClient2List(self):
        tcpClientSocket = self.tcpServer.nextPendingConnection()
        client = ConnectClient(tcpClientSocket)
        self.tcpClientList.append(client)
        tcpClientSocket.readyRead.connect(self.slotDataReceived)
        tcpClientSocket.disconnected.connect(self.slotDisconnected)
        self.ui.onlineNumLabel.setText(str(len(self.tcpClientList)))

    def slotDataReceived(self):
        tcpClientSocket = self.sender()
        recvData = ''
        while tcpClientSocket.bytesAvailable() > 0:
            recvData += str(tcpClientSocket.read(tcpClientSocket.bytesAvailable()), encoding='utf-8')
        self.ui.contentListWidget.addItem(recvData)
        self.ui.contentListWidget.scrollToBottom()
        self._parseData(recvData, tcpClientSocket)
        # 实现信息的广播, tcpClientList中保存了所有与服务器相连的TcpClientSocket对象
        for client in self.tcpClientList:
            client.socket.write(bytes(recvData, encoding='utf-8'))

    def slotDisconnected(self):
        # 从tcpClientList列表中将断开连接的TcpClientSocket对象删除
        tcpClientSocket = self.sender()
        idx = self._findClient(tcpClientSocket)
        if idx >= 0:
            del (self.tcpClientList[idx])
        self.ui.onlineNumLabel.setText(str(len(self.tcpClientList)))

    def _findClient(self, socket):
        for idx, client in enumerate(self.tcpClientList):
            if client.socket is socket:
                return idx
        return -1

    def _parseData(self, data, socket):
        if data.startswith('[+]'):
            name = data.split(':')[0][4:]
            idx = self._findClient(socket)
            if idx >= 0:
                self.tcpClientList[idx].name = name
                self.ui.userListWidget.addItem(name)
        elif data.startswith('[-]'):
            idx = self._findClient(socket)
            if idx >= 0:
                self.ui.userListWidget.takeItem(idx)

    def closeEvent(self, event):
        if self.isUp:
            msg = 'Are you sure to close the chat room ?'
            reply = QMessageBox().warning(self, 'Quit', msg, QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if reply == QMessageBox.Yes:
                self.closeRoom()
                event.accept()
            else:
                event.ignore()
        else:
            event.accept()
示例#13
0
class QidiConnectionManager(QObject):
    progressChanged = pyqtSignal(int)
    conectionStateChanged = pyqtSignal(bool)
    updateDone = pyqtSignal()

    def __init__(self, ip_addr, temp_gcode_file, log_enabled=False):
        super().__init__()
        self._ip = QHostAddress(ip_addr)
        self._localTempGcode = temp_gcode_file
        self._port = 3000
        self.BUFSIZE = 1280
        self._file_encode = 'utf-8'
        self._abort = False
        self._filename = None
        self._log_enabled = log_enabled
        self._connected = False
        self._socket = QUdpSocket(self)
        self._last_reply = None
        self._isPrinting = False
        self._isIdle = False
        self._print_now = 0
        self._print_total = 0
        self._busy = False
        self._printing_filename = ""
        self._firmware_ver = ""
        self._printing_time = 0
        self._update_fail_cnt = 0
        self._last_times = []
        self._status = {}
        self._mutex = Lock()
        self._config = {'e_mm_per_step': '0.0',
                        's_machine_type': '0',
                        's_x_max': '0.0',
                        's_y_max': '0.0',
                        's_z_max': '0.0',
                        'x_mm_per_step': '0.0',
                        'y_mm_per_step': '0.0',
                        'z_mm_per_step': '0.0'}
        self.__log("d", "LocalPort: {}", self._socket.localPort())

    def __log(self, log_type: str, message: str, *args, **kwargs):
        if self._log_enabled:
            Logger.log(log_type, message, *args, **kwargs)

    def __send(self, cmd):
        new_command = cast(str, cmd).encode(self._file_encode, 'ignore') if type(cmd) is str else cast(bytes, cmd)  # type: bytes
        self._socket.writeDatagram(new_command, self._ip, self._port)

    def __recieve(self, timeout_ms=100):
        if timeout_ms > 0:
            start = Timer() + timeout_ms / 1000.0
            while Timer() < start and not self._socket.hasPendingDatagrams():
                pass
        msg = ''
        res = QidiResult.TIMEOUT
        while self._socket.hasPendingDatagrams():
            datagram, host, port = self._socket.readDatagram(self._socket.pendingDatagramSize())
            if datagram:
                msg += datagram.decode(self._file_encode, 'ignore')
                res = QidiResult.SUCCES

        if 'Error:Wifi reboot' in msg or 'Error:IP is connected' in msg:
            res = QidiResult.DISCONNECTED
            self._connected = False
            self.conectionStateChanged.emit(self._connected)
        return msg, res

    def sendCommand(self, cmd):
        result = self._mutex.acquire(blocking=True, timeout=1)
        if result:
            self.__send(cmd)
            self._mutex.release()
        else:
            self.__log("d", 'timeout: lock not available')

    def request(self, cmd, timeout_ms=100, retries=1):
        tryCnt = 0
        msg = ''
        res = QidiResult.TIMEOUT
        self.__recieve(0)  # discard pending datagrams
        while tryCnt < retries:
            tryCnt += 1
            if type(cmd) is str:
                self.__log("d", '[{}]sending cmd to {}: {}', tryCnt, self._ip.toString(), cmd)
            if self.abort is True:
                return '', QidiResult.ABORTED
            if not self._connected:
                return '', QidiResult.DISCONNECTED
            self.__send(cmd)
            msg, res = self.__recieve(timeout_ms)
            if res == QidiResult.SUCCES:
                if type(cmd) is str:  # Log reply message only for str commands
                    self.__log("d", 'got reply from {}: {}', self._ip.toString(), str(msg).rstrip())
                break
        return msg, res

    def abort(self):
        self.abort = True

    def connect(self, retries=1):
        with self._mutex:
            return self.__connect(retries)

    def __connect(self, retries=1):
        tryCnt = 0
        while tryCnt < retries and self._connected == False:
            tryCnt += 1
            self.__send("M4001")
            msg, res = self.__recieve()
            if res is not QidiResult.SUCCES:
                self.__log("w", '{} Connection timeout ', self._ip.toString())
                continue
            self.__log("d", 'Connected')
            msg = msg.rstrip()
            self.__log("d", msg)
            msgs = msg.split(' ')
            for item in msgs:
                _ = item.split(':')
                if len(_) == 2:
                    id = _[0]
                    value = _[1]
                    if id == 'X':
                        self._config["x_mm_per_step"] = value
                    elif id == 'Y':
                        self._config["y_mm_per_step"] = value
                    elif id == 'Z':
                        self._config["z_mm_per_step"] = value
                    elif id == 'E':
                        self._config["e_mm_per_step"] = value
                    elif id == 'T':
                        _ = value.split('/')
                        if len(_) == 5:
                            self._config["s_machine_type"] = _[0]
                            self._config["s_x_max"] = _[1]
                            self._config["s_y_max"] = _[2]
                            self._config["s_z_max"] = _[3]
                    elif id == 'U':
                        self._file_encode = value.replace("'", '')
            self._connected = True
            msg, res = self.request('M4002 ', 2000, 2)
            if res == QidiResult.SUCCES:
                if 'ok ' in msg:
                    msg = msg.rstrip()
                    msg = msg.split('ok ')
                    self._firmware_ver = msg[1]
            self.conectionStateChanged.emit(self._connected)
            return True
        return False

    def __compress_gcode(self):
        exePath = None
        if Platform.isWindows():
            exePath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'VC_compress_gcode.exe')
        elif Platform.isOSX():
            exePath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'VC_compress_gcode_MAC')
        else:
            self.__log("w", "Could not find gcode compression tool")

        if exePath is not None and os.path.exists(exePath):
            cmd = '"' + exePath + '"' + ' "' + self._localTempGcode + '" ' + self._config["x_mm_per_step"] + ' ' + self._config["y_mm_per_step"] + ' ' + self._config["z_mm_per_step"] + ' ' + \
                self._config["e_mm_per_step"] + ' "' + os.path.dirname(self._localTempGcode) + '" ' \
                + self._config["s_x_max"] + ' ' + self._config["s_y_max"] + ' ' + self._config["s_z_max"] + ' ' + self._config["s_machine_type"]
            self.__log("d", cmd)

            ret = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
            self.__log("d", ret.stdout.read().decode('utf-8', 'ignore').rstrip())

            if os.path.exists(self._localTempGcode + '.tz'):  # check whether the compression succedded
                return True
            else:
                return False

    def __send_start_write(self, filename):
        self.__log("i", 'Creating file {}', filename)
        msg, res = self.request('M28 ' + filename, 2000, 3)
        if res == QidiResult.SUCCES:
            if 'Error' in msg:
                self.__log("e", 'cmd:' + msg)
                return QidiResult.WRITE_ERROR
            else:
                return QidiResult.SUCCES
        return res

    def __send_end_write(self, filename):
        self.__log("i", 'Closing file')
        msg, res = self.request('M29 ' + filename, 2000, 3)
        if res == QidiResult.SUCCES:
            if 'Error' in msg:
                self.__log("e", 'cmd:' + msg)
                return QidiResult.WRITE_ERROR
            else:
                return QidiResult.SUCCES
        return res

    def __send_file_block(self, buff, seek):
        check_sum = 0
        buff += b"000000"
        dataArray = bytearray(buff)
        seekArray = struct.pack('>I', seek)
        datSize = len(dataArray) - 6
        dataArray[datSize] = seekArray[3]
        dataArray[datSize + 1] = seekArray[2]
        dataArray[datSize + 2] = seekArray[1]
        dataArray[datSize + 3] = seekArray[0]
        for i in range(0, datSize + 4, 1):
            check_sum ^= dataArray[i]
        dataArray[datSize + 4] = check_sum
        dataArray[datSize + 5] = 131
        datSize = len(dataArray) - 6
        if datSize <= 0:
            raise Exception('error computing checksum!')
            return
        return self.request(dataArray, 2000, 3)

    def __send_file(self, fp):
        self.__log("i", 'begin sending file')
        lastProgress = seek = 0

        while True:
            try:
                if self._abort:
                    return QidiResult.ABORTED

                seek = fp.tell()
                data = fp.read(self.BUFSIZE)
                if int(100 * seek / self.__sendFileSize) > int(100 * lastProgress):
                    lastProgress = seek / self.__sendFileSize
                    progress = int(100 * lastProgress)
                    self.progressChanged.emit(progress)
                    sys.stdout.write('*')
                    sys.stdout.flush()
                if not data:
                    sys.stdout.write('\r\n')
                    self.__log("d", 'reach file end')
                    return QidiResult.SUCCES

                #self.__log("d","sending file block: {}", seek)
                msg, res = self.__send_file_block(data, seek)

                if res == QidiResult.SUCCES:
                    if 'ok' in msg:
                        continue
                    else:
                        self.__log("w", "got reply: " + msg)
                        if 'resend' in msg:
                            value = re.findall('resend \\d+', msg)
                            if value:
                                resend_offset = int(value[0].replace('resend ', ''))
                                fp.seek(resend_offset, 0)

                            else:
                                self.__log("d", 'bad offset:' + msg)
                                return QidiResult.WRITE_ERROR
                        elif 'Error' in msg:
                            return QidiResult.WRITE_ERROR
                        else:
                            return QidiResult.WRITE_ERROR
                else:
                    self.__log("e", 'send file block timeout')
                    continue
            except Exception as e:
                self.__log("w", str(e))
                return QidiResult.WRITE_ERROR

    def sendfile(self, filename):
        with self._mutex:
            ret = self.__sendfile(filename)
            return ret

    def __sendfile(self, filename):
        self._abort = False
        self._filename = None
        if not self._connected:
            if not self.__connect():
                return QidiResult.DISCONNECTED

        if os.path.exists(self._localTempGcode + '.tz'):
            os.remove(self._localTempGcode + '.tz')

        if self.__compress_gcode():
            filename += '.gcode.tz'
            send_file_path = self._localTempGcode + '.tz'
        else:
            filename += '.gcode'
            send_file_path = self._localTempGcode

        self.__log("d", 'file path: ' + send_file_path)

        try:
            self.__sendFileSize = os.path.getsize(send_file_path)
            self.__log("d", 'file size: {}', self.__sendFileSize)
            if self.__sendFileSize == 0:
                self.__log("e", 'file empty')
                return QidiResult.FILE_EMPTY

            with open(send_file_path, 'rb', buffering=1) as fp:
                if not self.__send_start_write(filename):
                    return QidiResult.WRITE_ERROR

                res = self.__send_file(fp)
                if res is not QidiResult.SUCCES:
                    return res

                if not self.__send_end_write(filename):
                    return QidiResult.WRITE_ERROR

        except Exception as e:
            self.__log("w", str(e))
            return QidiResult.WRITE_ERROR

        self._filename = filename
        return QidiResult.SUCCES

    def print(self):
        msg, res = self.request('M6030 ":' + self._filename + '" I1', 2000, 3)
        if res == QidiResult.SUCCES and 'Error' in msg:
            return QidiResult.FAIL
        return res

    def update(self):
        result = self._mutex.acquire(blocking=True, timeout=0.5)
        if result:
            ret = self.__update()
            if ret == QidiResult.SUCCES:
                self._update_fail_cnt = 0
                self.updateDone.emit()
            else:
                self._update_fail_cnt += 1
                if self._update_fail_cnt > 2:
                    self._connected = False
                    self.conectionStateChanged.emit(self._connected)
            self._mutex.release()
            return ret
        else:
            self.__log("d", 'timeout: lock not available')
            return QidiResult.TIMEOUT

    def __update(self):
        msg, res = self.request("M4000", 100, 3)
        if res == QidiResult.SUCCES:
            prev_printing_time = self._printing_time
            msg = msg.rstrip()
            msgs = msg.split(' ')
            for item in msgs:
                _ = item.split(':')
                try:
                    if len(_) == 2:
                        id = _[0]
                        value = _[1]
                        if id == 'B':
                            _ = value.split('/')
                            if len(_) == 2:
                                self._status["bed_nowtemp"] = _[0]
                                self._status["bed_targettemp"] = _[1]
                        elif id == 'E1':
                            _ = value.split('/')
                            if len(_) == 2:
                                self._status["e1_nowtemp"] = _[0]
                                self._status["e1_targettemp"] = _[1]
                        elif id == 'E2':
                            _ = value.split('/')
                            if len(_) == 2:
                                self._status["e2_nowtemp"] = _[0]
                                self._status["e2_targettemp"] = _[1]
                        elif id == 'D':
                            _ = value.split('/')
                            if len(_) == 3:
                                self._print_now = int(_[0])
                                self._print_total = int(_[1])
                                self._isIdle = _[2] is '1'
                        elif id == 'F':
                            _ = value.split('/')
                            if len(_) == 2:
                                self._status["fan"] = _[0]
                        elif id == 'X':
                            self._status["x_pos"] = value
                        elif id == 'Y':
                            self._status["y_pos"] = value
                        elif id == 'Z':
                            self._status["z_pos"] = value
                        elif id == 'T':
                            self._printing_time = int(value)
                except:
                    self.__log("e", "Could not parse M4000 reply: {}", msg)

            if self._isPrinting == False and self._printing_time > 0:
                self._last_times = []
                self._isPrinting = True
                msg, res = self.request("M4006", 100, 3)
                if res == QidiResult.SUCCES:
                    _ = msg.split("'")
                    if len(_) > 2:
                        self._printing_filename = _[1]
            elif self._printing_time == 0:
                self._isPrinting = False

        return res
示例#14
0
class LogServer(QTcpServer):
    def __init__(self, main_window, on_connection, log, stop_signal):
        super().__init__()
        self.log = log.getChild('TCP')

        self.log.info('Initializing')

        self.main_window = main_window
        self.on_connection = on_connection
        self.stop_signal = stop_signal

        self.host, self.port = CONFIG.listen_address
        self.host = QHostAddress(self.host)
        self.benchmark = CONFIG['benchmark']

        self.threads = {}  # socketDescriptor -> LogConnection
        self.connections = 0

    def start(self):
        self.log.info('Starting the server')
        if self.benchmark:
            self.log.debug('Starting a benchmark connection')
            tab_closed = asyncio.Event()
            new_conn = BenchmarkConnection(self, None, "benchmark",
                                           self.stop_signal, tab_closed,
                                           self.log)
            self.on_connection(new_conn, "benchmark", tab_closed)
            self.threads[None] = new_conn
            new_conn.start()

        result = self.listen(self.host, self.port)
        if not result:
            err_string = self.errorString()
            show_critical_dialog(self.main_window,
                                 'Error while starting the server', err_string)
        else:
            address = "{}:{}".format(self.host.toString(), self.port)
            self.main_window.set_status(
                'Server is listening on {}...'.format(address))

    def incomingConnection(self, socketDescriptor):
        self.connections += 1
        name = 'Logger {}'.format(self.connections)
        self.log.info('New connection: "{}"'.format(name))
        tab_closed = asyncio.Event()
        new_conn = LogConnection(self, socketDescriptor, name,
                                 self.stop_signal, tab_closed, self.log)
        self.on_connection(new_conn, name, tab_closed)
        new_conn.finished.connect(new_conn.deleteLater)
        new_conn.connection_finished.connect(self.cleanup_connection)
        new_conn.start()
        self.threads[int(socketDescriptor)] = new_conn

    def close_server(self):
        self.log.debug('Closing the server')
        self.close()
        self.stop_all_connections()

    def stop_all_connections(self):
        self.log.debug('Waiting for connection threads to stop')
        for _, thread in self.threads.items():
            thread.exit()
        for _, thread in self.threads.items():
            if not thread.wait(1000):
                self.log.error(
                    'Thread "{}" didn\'t stop in time, terminating...'.format(
                        thread))
                thread.terminate()
                self.log.error('Thread "{}" terminated'.format(thread))
        self.log.debug('All connections stopped')

    def cleanup_connection(self, socketDescriptor):
        try:
            del self.threads[socketDescriptor]
        except Exception as e:
            self.log.error('Bad socketDescriptor: {}'.format(socketDescriptor),
                           exc_info=True)