コード例 #1
0
class Server(QWidget):
    def __init__(self, model, prediction, vocabulary):
        super(Server, self).__init__()
        self.model = model
        self.prediction = prediction
        self.vocabulary = vocabulary
        self.resize(500, 450)

        # 1
        self.browser = QTextBrowser(self)

        self.v_layout = QVBoxLayout()
        self.v_layout.addWidget(self.browser)
        self.setLayout(self.v_layout)

        # 2
        self.server = QTcpServer(self)
        if not self.server.listen(QHostAddress.LocalHost, 8080):
            self.browser.append(self.server.errorString())
        self.server.newConnection.connect(self.new_socket_slot)

    def new_socket_slot(self):
        sock = self.server.nextPendingConnection()

        peer_address = sock.peerAddress().toString()
        peer_port = sock.peerPort()
        news = 'Connected with address {}, port{}'.format(
            peer_address, str(peer_port))
        self.browser.append(news)

        sock.readyRead.connect(lambda: self.read_data_slot(sock))
        sock.disconnected.connect(lambda: self.disconnected_slot(sock))

    # 3
    def read_data_slot(self, sock):
        while sock.bytesAvailable():
            datagram = sock.read(sock.bytesAvailable())
            message = datagram.decode()
            answer = self.get_answer(message).encode()
            sock.write(bytes(answer))

    def get_answer(self, message):
        sentence = pre_dosegment(message)
        sentence = ' '.join(sentence)
        prediction1 = self.model.test(str(sentence), self.vocabulary)
        query = match_question(prediction1, str(message))
        answer = self.prediction.run(query, prediction1)
        return answer

    # 4
    def disconnected_slot(self, sock):
        peer_address = sock.peerAddress().toString()
        peer_port = sock.peerPort()
        news = 'Disconnected with address {}, port {}'.format(
            peer_address, str(peer_port))
        self.browser.append(news)

        sock.close()
コード例 #2
0
class ReceiverEngine(QObject):
    newDataPacket = pyqtSignal(str, str)

    def __init__(self, parent=None, port=NetSettings.nodeDataPort):
        super().__init__(parent)
        self.__incomingConnections = dict(
        )  # QMap<QTcpSocket*, _IncomingConnection>
        self.__incomingConnectionsAddress = str()
        self.__incomingConnectionsPort = int()
        self.__server = None
        self.__signChecker = SignChecker()
        self.__serverPort = port

    def __del__(self):
        pass
        # self.stop()

    @pyqtSlot()
    def setMaxPendingConnections(self, numConnections: int):
        if not self.__server:
            return
        self.__server.setMapPendingConnections(numConnections)

    def isListening(self):
        if not self.__server:
            return False
        # SHOULD BE PROTECTED WITH MUTEX
        return self.__server.isListening()

    @pyqtSlot(str)
    def runReceiver(self, hostAddress: str):
        if not self.__server:
            self.__server = QTcpServer(self)
            self.__server.acceptError.connect(self.__error)
        if not self.__server.listen(
                QHostAddress(hostAddress),
                self.__serverPort) and not self.isListening():
            print("RECEIVER NOT STARTED", self.__server.errorString())
        else:
            self.__server.newConnection.connect(self.__newConnection)
            self.__incomingConnectionsAddress = hostAddress
            self.__incomingConnectionsPort = self.__serverPort
            print("RECEIVER STARTED")

    @pyqtSlot()
    def stop(self):
        if not self.__server:
            return
        if self.isListening():
            for socket in self.__incomingConnections.keys():
                socket.readyRead.disconnect()
                socket.disconnected.disconnect()
                socket.close()
            self.__incomingConnections.clear()

    @pyqtSlot()
    def __newConnection(self):
        socket = self.__server.nextPendingConnection()
        print("NEW CONN", socket.peerAddress().toString(), socket.peerPort())
        socket.setSocketOption(QAbstractSocket.LowDelayOption, 1)
        socket.setSocketOption(QAbstractSocket.KeepAliveOption, 0)

        # socket.setProperty("port", socket.peerPort())
        # socket.setProperty("address", socket.peerAddress().toString())
        incomingConnection = _IncomingConnection()
        incomingConnection.socketDescriptor = socket.socketDescriptor()
        incomingConnection.socket = socket
        # incomingConnection.socket.setReadBufferSize(1024)
        incomingConnection.socket.readyRead.connect(self.__readData)
        incomingConnection.socket.disconnected.connect(self.__disconnected)
        incomingConnection.buffer = QByteArray()
        incomingConnection.address = socket.peerAddress().toString()
        incomingConnection.port = socket.peerPort()
        self.__incomingConnections[socket] = incomingConnection

    @pyqtSlot()
    def __readData(self):
        socket = self.sender()
        # print("READ", socket.peerAddress().toString(), socket.peerPort())
        # print("read data from", socket.objectName())
        incomingConnection = self.__incomingConnections.get(socket, None)
        if incomingConnection:
            bytesAvailable = socket.bytesAvailable()
            # if self.__serverPort != NetSettings.nodeCommandPort:
            #     print(bytesAvailable, "READING FROM SOCKET", socket.peerPort())
            if bytesAvailable:
                incomingConnection.buffer.append(socket.read(bytesAvailable))
                while incomingConnection.receivingPacketSize == 0 and incomingConnection.buffer.size() >= 4 \
                        or incomingConnection.receivingPacketSize > 0 and incomingConnection.buffer.size() >= incomingConnection.receivingPacketSize:
                    if incomingConnection.receivingPacketSize == 0 and incomingConnection.buffer.size(
                    ) >= 4:
                        incomingConnection.receivingPacketSize = self.__bytesToInt(
                            incomingConnection.buffer.left(4))
                        incomingConnection.buffer.remove(0, 4)
                    if incomingConnection.receivingPacketSize > 0 and incomingConnection.buffer.size(
                    ) >= incomingConnection.receivingPacketSize:
                        packet = bytes(
                            incomingConnection.buffer.left(
                                incomingConnection.receivingPacketSize)
                        ).decode()
                        # if self.__signChecker.checkTran(packet):
                        self.newDataPacket.emit(incomingConnection.address,
                                                packet)
                        incomingConnection.buffer.remove(
                            0, incomingConnection.receivingPacketSize)
                        incomingConnection.receivingPacketSize = 0
        else:
            print("Address disconnected already ")
            # raise Exception("ERROR WITH ADDRESS")

    @pyqtSlot()
    def __disconnected(self):
        socket = self.sender()
        print("disconnected from ", socket.objectName())
        self.__incomingConnections.pop(socket, None)

    @pyqtSlot()
    def __error(self):
        server = self.sender()
        print("ERROR", server.errorString())

    def __bytesToInt(self, data: QByteArray):
        temp = int().from_bytes(data, byteorder="little")
        return temp
コード例 #3
0
ファイル: fortuneserver.py プロジェクト: Axel-Erfurt/pyqt5
class Server(QDialog):
    FORTUNES = (
        "You've been leading a dog's life. Stay off the furniture.",
        "You've got to think about tomorrow.",
        "You will be surprised by a loud noise.",
        "You will feel hungry again in another hour.",
        "You might have mail.",
        "You cannot kill time without injuring eternity.",
        "Computers are not intelligent. They only think they are.")

    def __init__(self, parent=None):
        super(Server, self).__init__(parent)

        self.tcpServer = None
        self.networkSession = None

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

        manager = QNetworkConfigurationManager()
        if manager.capabilities() & QNetworkConfigurationManager.NetworkSessionRequired:
            settings = QSettings(QSettings.UserScope, 'QtProject')
            settings.beginGroup('QtNetwork')
            id = settings.value('DefaultNetworkConfiguration', '')
            settings.endGroup()

            config = manager.configurationFromIdentifier(id)
            if config.state() & QNetworkConfiguration.Discovered == 0:
                config = manager.defaultConfiguration()

            self.networkSession = QNetworkSession(config, self)
            self.networkSession.opened.connect(self.sessionOpened)

            self.statusLabel.setText("Opening network session.")
            self.networkSession.open()
        else:
            self.sessionOpened()

        quitButton.clicked.connect(self.close)
        self.tcpServer.newConnection.connect(self.sendFortune)

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

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

        self.setWindowTitle("Fortune Server")

    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 sendFortune(self):
        fortune = self.FORTUNES[random.randint(0, len(self.FORTUNES) - 1)]

        block = QByteArray()
        out = QDataStream(block, QIODevice.WriteOnly)
        out.setVersion(QDataStream.Qt_4_0)
        out.writeUInt16(0)
        out.writeQString(fortune)
        out.device().seek(0)
        out.writeUInt16(block.size() - 2)

        clientConnection = self.tcpServer.nextPendingConnection()
        clientConnection.disconnected.connect(clientConnection.deleteLater)

        clientConnection.write(block)
        clientConnection.disconnectFromHost()
コード例 #4
0
class TcpS(QDialog, Ui_TcpServer):
    """
    文件传输服务器
    """

    sendFileName = pyqtSignal(str)

    def __init__(self, parent=None):
        """
        一些初始设置
        """
        super(TcpS, self).__init__(parent)
        self.setupUi(self)
        self.payloadSize = 64 * 1024
        # 读取数据64KB

        self.totalBytes = 0
        # 总大小

        self.bytesWritten = 0
        # 保存的数据

        self.bytesToWrite = 0
        # 每次减少连接写的数据量大小

        self.theFileName = ""
        # 文件名(不含路径)

        self.fileName = ""
        # 文件全名

        self.localFile = QFile()
        self.outBlock = QByteArray()
        # QByteArray()的对象,即字节数组

        self.time = QTime()
        self.initServer()

    def initServer(self):
        """
        网络设置初始化
        """
        self.tcpPort = 7788
        # 指定了TCP端口为7788

        self.tcpServer = QTcpServer(self)
        self.clientConnection = QTcpSocket(self)
        # 创建一个Tcp服务器和一个Tcp套接字

        self.tcpServer.newConnection.connect(self.sendMessage)
        # 当有新的连接来的时候发出newConnection信号,我们连接到sendMessage()函数。

        self.serverStatuslabel.setText("请选择要传送的文件")
        self.progressBar.reset()
        self.serverOpenBtn.setEnabled(True)
        self.serverSendBtn.setEnabled(False)
        self.tcpServer.close()
        # 显示我们开始创建的对话框,打开按钮是可用的,发送按钮是不可用的,进度条复位,先关闭服务器。

    def refused(self):
        """
        对端拒绝接收文件,主程序会调用服务器的refused()函数,关闭服务器。
        """
        self.tcpServer.close()
        self.serverStatuslabel.setText("对方拒绝接收")

    def closeEvent(self, event):
        """
        关闭事件
        """
        self.on_serverCloseBtn_clicked()
        # 产生关闭事件,直接调用关闭窗口按钮函数。

    def sendMessage(self):
        """
        发送文件
        """
        self.serverSendBtn.setEnabled(False)
        # 发送按钮不可用

        self.clientConnection = self.tcpServer.nextPendingConnection()
        # self.clientConnection作为连接的QTcpSocket对象返回下一个挂起的连接。

        self.clientConnection.bytesWritten.connect(self.updateClientProgress)
        # 当连接中每次将数据有效载荷写入设备的当前写通道时,都会发出此信号。在此有效负载中写入的数据量为字节数。

        self.serverStatuslabel.setText("开始传送文件 {} !".format(self.theFileName))

        self.localFile = QFile(self.fileName)
        if not (self.localFile.open(QFile.ReadOnly)):
            errorMsg = "无法读取文件 {}:\n {}".format(self.fileName,
                                                self.localFile.errorString())
            QMessageBox.warning(self, "应用程序", errorMsg)
            return
        # 尝试打开文件,要是存在问题就报错。

        self.serverCloseBtn.setText("取消")

        self.totalBytes = self.localFile.size()
        # 记录一下需要传输的文件大小。单位:字节

        sendOut = QDataStream(self.outBlock, QIODevice.WriteOnly)
        # 这里的self.outBlock是QByteArray()的对象,即字节数组;QIODevice的模式为WriteOnly

        sendOut.setVersion(QDataStream.Qt_5_4)
        # 设定QDataStream的版本为Qt_5_4

        self.time.start()
        # 开始计时

        currentFile = self.fileName.split("/")[-1]
        # 传输的文件名

        sendOut.writeInt64(0)
        sendOut.writeInt64(0)
        sendOut.writeQString(currentFile)
        self.totalBytes += self.outBlock.size()
        # 在sendOut中写入文件名以及文件名和文件的大小,大小都是以字节为单位的。

        sendOut.device().seek(0)
        sendOut.writeInt64(self.totalBytes)
        sendOut.writeInt64(self.outBlock.size() - 2)
        # QIODevice读写位置移动到0。然后分别写入总的大小和文件名大小。

        self.bytesToWrite = self.totalBytes - self.clientConnection.write(
            self.outBlock)
        # 待传输文件的大小。

        self.outBlock.resize(0)
        # outBlock清零。

    def updateClientProgress(self, numBytes):
        """
        发送进度显示
        """
        qApp.processEvents()
        # 长时间工作用,以免窗口假死

        self.bytesWritten += numBytes
        if self.bytesWritten > 0:
            self.block = self.localFile.read(
                min(self.bytesToWrite, self.payloadSize))
            self.bytesToWrite -= self.clientConnection.write(self.block)
        else:
            self.localFile.close()
        # 当我们待写入的字节数大于0时,我们每次读取的数据都是小于等于self.payloadSize的,这个self.payloadSize我们定义是64KB。
        # self.bytesToWrite每次减少连接写的数据量大小。
        # 要是待写入的字节数小于等于0,则关闭文件。

        byteSent = self.bytesWritten / (1024 * 1024)
        # 已经写了多少文件
        useTime = self.time.elapsed() / 1000
        # 传输用了多长时间
        speed = self.bytesWritten / useTime / (1024 * 1024)
        # 传输速度
        total = self.totalBytes / (1024 * 1024)
        # 总大小
        left = (total - byteSent) / speed
        # 表示剩余时间

        if byteSent < 0.01:
            byteSent = self.bytesWritten / 1024
            speed = self.bytesWritten / useTime / 1024
            total = self.totalBytes / 1024
            if left > 0:
                sendInfo = "已发送 {0:.2f}KB({1:.2f}KB/s)\n共{2:.2f}KB 已用时:{3:.1f}秒\n 估计剩余时间:{4:.1f}秒".format(
                    byteSent, speed, total, useTime, left)
            else:
                sendInfo = "已发送 {0:.2f}KB({1:.2f}KB/s)\n共{2:.2f}KB 用时:{3:.1f}秒\n".format(
                    byteSent, speed, total, useTime)
        else:
            if left > 0:
                sendInfo = "已发送 {0:.2f}MB({1:.2f}MB/s)\n共{2:.2f}MB 已用时:{3:.1f}秒\n 估计剩余时间:{4:.1f}秒".format(
                    byteSent, speed, total, useTime, left)
            else:
                sendInfo = "已发送 {0:.2f}MB({1:.2f}MB/s)\n共{2:.2f}MB 用时:{3:.1f}秒\n".format(
                    byteSent, speed, total, useTime)

        self.progressBar.setMaximum(total)
        self.progressBar.setValue(byteSent)

        if self.bytesWritten == self.totalBytes:
            self.serverCloseBtn.setText("关闭")
        # 进度条显示的方式,以及当传输的字节数等于总的字节数的时候,按钮就显示关闭。

        self.serverStatuslabel.setText(sendInfo)

    @pyqtSlot()
    def on_serverOpenBtn_clicked(self):
        """
        打开文件准备发送
        """
        self.fileName = QFileDialog.getOpenFileName(self, '打开文件', './')[0]
        if self.fileName:
            self.theFileName = self.fileName.split("/")[-1]
            self.serverStatuslabel.setText("要传送的文件为:{}".format(
                self.theFileName))
            self.serverSendBtn.setEnabled(True)
            self.serverOpenBtn.setEnabled(False)

    @pyqtSlot()
    def on_serverSendBtn_clicked(self):
        """
        发送文件,等待接收
        """
        if not (self.tcpServer.listen(QHostAddress.Any, self.tcpPort)):
            errorMsg = self.tcpServer.errorString()
            QMessageBox.warning(self, "错误", "发送失败:\n {}".format(errorMsg))
            self.TcpServer.close()
            return

        self.serverStatuslabel.setText("等待对方接收... ...")
        self.serverSendBtn.setEnabled(False)
        self.sendFileName.emit(self.theFileName)

    @pyqtSlot()
    def on_serverCloseBtn_clicked(self):
        """
        取消或者关闭
        """
        if self.tcpServer.isListening():
            self.tcpServer.close()
            if self.localFile.isOpen():
                self.localFile.close()
            self.clientConnection.abort()

        if self.serverCloseBtn.text() == "取消":
            self.serverCloseBtn.setText("关闭")
        else:
            self.close()
            self.serverOpenBtn.setEnabled(True)
            self.serverSendBtn.setEnabled(False)
            self.progressBar.reset()
            self.totalBytes = 0
            self.bytesWritten = 0
            self.bytesToWrite = 0
            self.serverStatuslabel.setText("请选择要传送的文件")
コード例 #5
0
class Server(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        self.serverOpen = False
        self.tcpServer = None
        self.tcpServerConnection = None

        self.textEdit = None
        self.lineEdit = None

        self.create_widgets()

    def create_widgets(self):
        self.tcpServer = QTcpServer()

        self.textEdit = QTextEdit()
        self.textEdit.setReadOnly(True)

        self.lineEdit = QLineEdit()
        self.lineEdit.setPlaceholderText("Enter response")
        self.lineEdit.setMaxLength(50)
        self.lineEdit.setEnabled(True)

        vBox = QVBoxLayout()
        vBox.addWidget(self.textEdit)
        vBox.addWidget(self.lineEdit)
        self.setLayout(vBox)

        self.tcpServer.newConnection.connect(self.accept_connection)

    def add_message(self, message):
        self.textEdit.moveCursor(QTextCursor.End)
        self.textEdit.insertPlainText(message)
        self.textEdit.moveCursor(QTextCursor.End)

    def open_server(self):
        if (len(self.lineEdit.text()) == 0):
            self.add_message("You must enter a response\n")
            QMessageBox.critical(self, "Error", "You must enter a response")
            return False

        self.tcpServer.listen(QHostAddress(__serverUrl__), 9000)

        self.serverOpen = self.tcpServer.isListening()

        if (self.serverOpen):
            serverAddress = self.tcpServer.serverAddress().toString()
            serverPort = self.tcpServer.serverPort()
            self.add_message("Server opened on %s on port %d\n" %
                             (serverAddress, serverPort))
            self.lineEdit.setEnabled(False)
        else:
            self.add_message(self.tcpServer.errorString())
            QMessageBox.critical(self, "Error", self.tcpServer.errorString())

        return True

    def accept_connection(self):
        self.tcpServerConnection = self.tcpServer.nextPendingConnection()
        self.tcpServerConnection.readyRead.connect(self.receive_data)
        self.tcpServerConnection.disconnected.connect(self.socket_disconnected)

        peerAddress = self.tcpServerConnection.peerAddress().toString()
        peerPort = self.tcpServerConnection.peerPort()
        self.add_message("Connected to %s on port %d\n" %
                         (peerAddress, peerPort))

    def receive_data(self):
        rxData = self.tcpServerConnection.readAll()
        self.add_message("Received '" + rxData.data().decode('utf8') + "'\n")
        txString = self.lineEdit.text()
        self.tcpServerConnection.write(txString.encode())
        self.add_message("Wrote '" + txString + "'\n")

    def socket_disconnected(self):
        self.add_message("Disconnected from client\n")

    def close_server(self):
        if (self.serverOpen):
            self.tcpServer.close()
            self.lineEdit.setEnabled(True)
コード例 #6
0
class Dialog(QDialog):
    TotalBytes = 50 * 1024 * 1024
    PayloadSize = 65536

    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)

        self.tcpServer = QTcpServer()
        self.tcpClient = QTcpSocket()
        self.bytesToWrite = 0
        self.bytesWritten = 0
        self.bytesReceived = 0

        self.clientProgressBar = QProgressBar()
        self.clientStatusLabel = QLabel("Client ready")
        self.serverProgressBar = QProgressBar()
        self.serverStatusLabel = QLabel("Server ready")

        self.startButton = QPushButton("&Start")
        self.quitButton = QPushButton("&Quit")

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

        self.startButton.clicked.connect(self.start)
        self.quitButton.clicked.connect(self.close)
        self.tcpServer.newConnection.connect(self.acceptConnection)
        self.tcpClient.connected.connect(self.startTransfer)
        self.tcpClient.bytesWritten.connect(self.updateClientProgress)
        self.tcpClient.error.connect(self.displayError)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.clientProgressBar)
        mainLayout.addWidget(self.clientStatusLabel)
        mainLayout.addWidget(self.serverProgressBar)
        mainLayout.addWidget(self.serverStatusLabel)
        mainLayout.addStretch(1)
        mainLayout.addSpacing(10)
        mainLayout.addWidget(buttonBox)
        self.setLayout(mainLayout)

        self.setWindowTitle("Loopback")

    def start(self):
        self.startButton.setEnabled(False)

        QApplication.setOverrideCursor(Qt.WaitCursor)

        self.bytesWritten = 0
        self.bytesReceived = 0

        while not self.tcpServer.isListening() and not self.tcpServer.listen():
            ret = QMessageBox.critical(
                self,
                "Loopback",
                "Unable to start the test: %s." % self.tcpServer.errorString(),
                QMessageBox.Retry | QMessageBox.Cancel,
            )
            if ret == QMessageBox.Cancel:
                return

        self.serverStatusLabel.setText("Listening")
        self.clientStatusLabel.setText("Connecting")

        self.tcpClient.connectToHost(QHostAddress(QHostAddress.LocalHost),
                                     self.tcpServer.serverPort())

    def acceptConnection(self):
        self.tcpServerConnection = self.tcpServer.nextPendingConnection()
        self.tcpServerConnection.readyRead.connect(self.updateServerProgress)
        self.tcpServerConnection.error.connect(self.displayError)

        self.serverStatusLabel.setText("Accepted connection")
        self.tcpServer.close()

    def startTransfer(self):
        self.bytesToWrite = Dialog.TotalBytes - self.tcpClient.write(
            QByteArray(Dialog.PayloadSize, "@"))
        self.clientStatusLabel.setText("Connected")

    def updateServerProgress(self):
        self.bytesReceived += self.tcpServerConnection.bytesAvailable()
        self.tcpServerConnection.readAll()

        self.serverProgressBar.setMaximum(Dialog.TotalBytes)
        self.serverProgressBar.setValue(self.bytesReceived)
        self.serverStatusLabel.setText("Received %dMB" % (self.bytesReceived /
                                                          (1024 * 1024)))

        if self.bytesReceived == Dialog.TotalBytes:
            self.tcpServerConnection.close()
            self.startButton.setEnabled(True)
            QApplication.restoreOverrideCursor()

    def updateClientProgress(self, numBytes):
        self.bytesWritten += numBytes
        if self.bytesToWrite > 0:
            self.bytesToWrite -= self.tcpClient.write(
                QByteArray(min(self.bytesToWrite, Dialog.PayloadSize), "@"))

        self.clientProgressBar.setMaximum(Dialog.TotalBytes)
        self.clientProgressBar.setValue(self.bytesWritten)
        self.clientStatusLabel.setText("Sent %dMB" % (self.bytesWritten /
                                                      (1024 * 1024)))

    def displayError(self, socketError):
        if socketError == QTcpSocket.RemoteHostClosedError:
            return

        QMessageBox.information(
            self,
            "Network error",
            "The following error occured: %s." % self.tcpClient.errorString(),
        )

        self.tcpClient.close()
        self.tcpServer.close()
        self.clientProgressBar.reset()
        self.serverProgressBar.reset()
        self.clientStatusLabel.setText("Client ready")
        self.serverStatusLabel.setText("Server ready")
        self.startButton.setEnabled(True)
        QApplication.restoreOverrideCursor()
コード例 #7
0
class Server(QDialog):
    FORTUNES = ("You've been leading a dog's life. Stay off the furniture.",
                "You've got to think about tomorrow.",
                "You will be surprised by a loud noise.",
                "You will feel hungry again in another hour.",
                "You might have mail.",
                "You cannot kill time without injuring eternity.",
                "Computers are not intelligent. They only think they are.")

    def __init__(self, parent=None):
        super(Server, self).__init__(parent)

        self.tcpServer = None
        self.networkSession = None

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

        manager = QNetworkConfigurationManager()
        if manager.capabilities(
        ) & QNetworkConfigurationManager.NetworkSessionRequired:
            settings = QSettings(QSettings.UserScope, 'QtProject')
            settings.beginGroup('QtNetwork')
            id = settings.value('DefaultNetworkConfiguration', '')
            settings.endGroup()

            config = manager.configurationFromIdentifier(id)
            if config.state() & QNetworkConfiguration.Discovered == 0:
                config = manager.defaultConfiguration()

            self.networkSession = QNetworkSession(config, self)
            self.networkSession.opened.connect(self.sessionOpened)

            self.statusLabel.setText("Opening network session.")
            self.networkSession.open()
        else:
            self.sessionOpened()

        quitButton.clicked.connect(self.close)
        self.tcpServer.newConnection.connect(self.sendFortune)

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

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

        self.setWindowTitle("Fortune Server")

    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 sendFortune(self):
        fortune = self.FORTUNES[random.randint(0, len(self.FORTUNES) - 1)]

        block = QByteArray()
        out = QDataStream(block, QIODevice.WriteOnly)
        out.setVersion(QDataStream.Qt_4_0)
        out.writeUInt16(0)
        out.writeQString(fortune)
        out.device().seek(0)
        out.writeUInt16(block.size() - 2)

        clientConnection = self.tcpServer.nextPendingConnection()
        clientConnection.disconnected.connect(clientConnection.deleteLater)

        clientConnection.write(block)
        clientConnection.disconnectFromHost()
コード例 #8
0
class ServerSocket(QObject):
    """Class defining a socket for the server."""

    listening = pyqtSignal(tuple)
    message_received = pyqtSignal(tuple)
    client_disconnected = pyqtSignal(str)

    def __init__(self):
        """Constructor."""
        QObject.__init__(self)

        self.__tcpServer = QTcpServer()

        self.__active_sockets = []

        self.__tcpServer.newConnection.connect(self.__new_connection)

    def __new_connection(self):
        """Method handling a new connection to the server."""
        # Connecting the new client
        client = self.__tcpServer.nextPendingConnection()
        client.readyRead.connect(self.read_message)
        client.disconnected.connect(self.__find_disconnected_client)
        client.disconnected.connect(client.deleteLater)  # Not sure
        self.__active_sockets.append(client)  # Hyper important !!!
        print("A new client connected from address '{}'.".format(
            client.peerAddress().toString()))

    def __find_disconnected_client(self):
        """Method trying to find the disconnected client."""
        self.client_disconnected.emit(self.sender().localAddress().toString())

        self.__active_sockets = []
        for socket in self.__tcpServer.children()[1:]:
            if int(socket.socketDescriptor()) <= 10000:  # Socket is active
                self.__active_sockets.append(socket)

    def get_available_ips(self):
        """Method returning the list of available ips."""
        return QNetworkInterface.allAddresses()

    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 read_message(self):
        """Method handling the messages."""
        for socket in self.__active_sockets:
            instr = socket.readAll()
            message = str(instr, encoding="utf8")
            if message:
                self.message_received.emit((message, socket))

    def __send_msg(self, message, socket):
        """Method effectively sending a message."""
        socket.write(bytes(message, encoding="utf8"))
        socket.flush()

    def send_message(self, message, recipient=None):
        """Method used to send a message to the clients."""
        if recipient:  # A single recipient was provided
            if type(recipient) is not str:  # Given socket directly
                self.__send_msg(message, recipient)
            else:  # Given ip address
                for socket in self.__active_sockets:
                    if socket.peerAddress().toString() == recipient:
                        self.__send_msg(message, socket)
        else:  # Send for everyone
            for socket in self.__active_sockets:
                self.__send_msg(message, socket)

            # block = QByteArray()
            # out = QDataStream(block, QIODevice.ReadWrite)
            # out.setVersion(QDataStream.Qt_5_0)
            # out.writeUInt16(0)
            # message = bytes(message, encoding="utf8")
            # out.writeString(message)
            # out.device().seek(0)
            # out.writeUInt16(block.size() - 2)
            # socket.write(block)

    def get_address(self):
        """Method returning the adress."""
        return self.__tcpServer.serverAddress()

    def get_port(self):
        """Method returning the port."""
        return self.__tcpServer.serverPort()
コード例 #9
0
class CodeExecutor:
    """
    This class is responsible for executing code (when starting Tribler in debug mode).
    The protocol to execute code is as follows.
    First, a client that wants to execute some code opens a connection with the TCP server and sends the
    string: <code in base64 format> <task_id>\n
    This code will be executed and the result will be sent to the client in the following format:
    result <result> <task_id>\n.
    If Tribler crashes, the server sends the following result: crash <stack trace in base64 format>

    Note that the socket uses the newline as separator.
    """

    def __init__(self, port, shell_variables=None):
        self.logger = logging.getLogger(self.__class__.__name__)
        self.tcp_server = QTcpServer()
        self.sockets = []
        self.stack_trace = None
        if not self.tcp_server.listen(port=port):
            self.logger.error("Unable to start code execution socket! Error: %s", self.tcp_server.errorString())
        else:
            connect(self.tcp_server.newConnection, self._on_new_connection)

        self.shell = Console(locals=shell_variables or {}, logger=self.logger)

    def _on_new_connection(self):
        self.logger.info("CodeExecutor has new connection")

        while self.tcp_server.hasPendingConnections():
            socket = self.tcp_server.nextPendingConnection()
            connect(socket.readyRead, self._on_socket_read_ready)
            connect(socket.disconnected, self._on_socket_disconnect(socket))
            self.sockets.append(socket)

            # If Tribler has crashed, notify the other side immediately
            if self.stack_trace:
                self.on_crash(self.stack_trace)

    def run_code(self, code, task_id):
        self.logger.info(f"Run code for task {task_id}")
        self.logger.debug(f"Code for execution:\n{code}")

        try:
            self.shell.runcode(code)
        except SystemExit:
            pass

        if self.shell.last_traceback:
            self.on_crash(self.shell.last_traceback)
            return

        self.logger.info("Code execution with task %s finished:", task_id)

        return_value = b64encode(self.shell.locals.get('return_value', '').encode('utf-8'))
        for socket in self.sockets:
            socket.write(b"result %s %s\n" % (return_value, task_id))

    def on_crash(self, exception_text):
        self.logger.error(f"Crash in CodeExecutor:\n{exception_text}")

        self.stack_trace = exception_text
        for socket in self.sockets:
            socket.write(b"crash %s\n" % b64encode(exception_text.encode('utf-8')))

    def _on_socket_read_ready(self):
        data = bytes(self.sockets[0].readAll())
        parts = data.split(b" ")
        if len(parts) != 2:
            return

        try:
            code = b64decode(parts[0]).decode('utf8')
            task_id = parts[1].replace(b'\n', b'')
            self.run_code(code, task_id)
        except binascii.Error:
            self.logger.error("Invalid base64 code string received!")

    def _on_socket_disconnect(self, socket):
        def on_socket_disconnect_handler():
            self.sockets.remove(socket)
        return on_socket_disconnect_handler
コード例 #10
0
class TcpS(QDialog, Ui_TcpServer):
    """
    Class documentation goes here.
    """

    sendFileName = pyqtSignal(str)

    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget
        @type QWidget
        """
        super(TcpS, self).__init__(parent)
        self.setupUi(self)
        self.payloadSize = 64 * 1024
        self.totalBytes = 0
        self.bytesWritten = 0
        self.bytesToWrite = 0
        self.theFileName = ""
        self.fileName = ""
        self.localFile = QFile()
        self.outBlock = QByteArray()
        self.time = QTime()
        self.initServer()

    def initServer(self):
        """
        网络设置初始化
        """
        self.tcpPort = 7788
        self.tcpServer = QTcpServer(self)
        self.clientConnection = QTcpSocket(self)
        self.tcpServer.newConnection.connect(self.sendMessage)
        self.serverStatuslabel.setText("请选择要传送的文件")
        self.progressBar.reset()
        self.serverOpenBtn.setEnabled(True)
        self.serverSendBtn.setEnabled(False)
        self.tcpServer.close()

    def refused(self):
        """
        对端拒绝接收文件
        """
        self.tcpServer.close()
        self.serverStatuslabel.setText("对方拒绝接收")

    def closeEvent(self, event):
        """
        关闭事件
        """
        self.on_serverCloseBtn_clicked()

    def sendMessage(self):
        """
        发送文件
        """
        self.serverSendBtn.setEnabled(False)
        self.clientConnection = self.tcpServer.nextPendingConnection()
        self.clientConnection.bytesWritten.connect(self.updateClientProgress)
        self.serverStatuslabel.setText("开始传送文件 {} !".format(self.theFileName))

        self.localFile = QFile(self.fileName)
        if not (self.localFile.open(QFile.ReadOnly)):
            errorMsg = "无法读取文件 {}:\n {}".format(self.fileName,
                                                self.localFile.errorString())
            QMessageBox.warning(self, "应用程序", errorMsg)
            return

        self.serverCloseBtn.setText("取消")

        self.totalBytes = self.localFile.size()  #单位:字节
        sendOut = QDataStream(self.outBlock, QIODevice.WriteOnly)
        sendOut.setVersion(QDataStream.Qt_5_4)
        self.time.start()
        currentFile = self.fileName.split("/")[-1]
        sendOut.writeInt64(0)
        sendOut.writeInt64(0)
        sendOut.writeQString(currentFile)
        self.totalBytes += self.outBlock.size()
        sendOut.device().seek(0)
        sendOut.writeInt64(self.totalBytes)
        sendOut.writeInt64(self.outBlock.size() - 2)
        self.bytesToWrite = self.totalBytes - self.clientConnection.write(
            self.outBlock)
        self.outBlock.resize(0)

    def updateClientProgress(self, numBytes):
        """
        发送进度显示
        """
        qApp.processEvents()
        self.bytesWritten += numBytes
        if self.bytesWritten > 0:
            self.block = self.localFile.read(
                min(self.bytesToWrite, self.payloadSize))
            self.bytesToWrite -= self.clientConnection.write(self.block)
        else:
            self.localFile.close()

        byteSent = self.bytesWritten / (1024 * 1024)
        useTime = self.time.elapsed() / 1000
        speed = self.bytesWritten / useTime / (1024 * 1024)
        total = self.totalBytes / (1024 * 1024)
        left = (total - byteSent) / speed

        if byteSent < 0.01:
            byteSent = self.bytesWritten / 1024
            speed = self.bytesWritten / useTime / 1024
            total = self.totalBytes / 1024
            if left > 0:
                sendInfo = "已发送 {0:.2f}KB({1:.2f}KB/s)\n共{2:.2f}KB 已用时:{3:.1f}秒\n 估计剩余时间:{4:.1f}秒".format(
                    byteSent, speed, total, useTime, left)
            else:
                sendInfo = "已发送 {0:.2f}KB({1:.2f}KB/s)\n共{2:.2f}KB 用时:{3:.1f}秒\n".format(
                    byteSent, speed, total, useTime)
        else:
            if left > 0:
                sendInfo = "已发送 {0:.2f}MB({1:.2f}MB/s)\n共{2:.2f}MB 已用时:{3:.1f}秒\n 估计剩余时间:{4:.1f}秒".format(
                    byteSent, speed, total, useTime, left)
            else:
                sendInfo = "已发送 {0:.2f}MB({1:.2f}MB/s)\n共{2:.2f}MB 用时:{3:.1f}秒\n".format(
                    byteSent, speed, total, useTime)

        self.progressBar.setMaximum(total)
        self.progressBar.setValue(byteSent)

        if self.bytesWritten == self.totalBytes:
            self.serverCloseBtn.setText("关闭")

        self.serverStatuslabel.setText(sendInfo)

    @pyqtSlot()
    def on_serverOpenBtn_clicked(self):
        """
        打开文件
        """
        self.fileName = QFileDialog.getOpenFileName(self, '打开文件', './')[0]
        if self.fileName:
            self.theFileName = self.fileName.split("/")[-1]
            self.serverStatuslabel.setText("要传送的文件为:{}".format(
                self.theFileName))
            self.serverSendBtn.setEnabled(True)
            self.serverOpenBtn.setEnabled(False)

    @pyqtSlot()
    def on_serverSendBtn_clicked(self):
        """
        发送文件
        """
        if not (self.tcpServer.listen(QHostAddress.Any, self.tcpPort)):
            errorMsg = self.tcpServer.errorString()
            QMessageBox.warning(self, "错误", "发送失败:\n {}".format(errorMsg))
            self.TcpServer.close()
            return

        self.serverStatuslabel.setText("等待对方接收... ...")
        self.serverSendBtn.setEnabled(False)
        self.sendFileName.emit(self.theFileName)

    @pyqtSlot()
    def on_serverCloseBtn_clicked(self):
        """
        取消或者关闭
        """
        if self.tcpServer.isListening():
            self.tcpServer.close()
            if self.localFile.isOpen():
                self.localFile.close()
            self.clientConnection.abort()

        if self.serverCloseBtn.text() == "取消":
            self.serverCloseBtn.setText("关闭")
        else:
            self.close()
            self.serverOpenBtn.setEnabled(True)
            self.serverSendBtn.setEnabled(False)
            self.progressBar.reset()
            self.totalBytes = 0
            self.bytesWritten = 0
            self.bytesToWrite = 0
            self.serverStatuslabel.setText("请选择要传送的文件")
コード例 #11
0
ファイル: tcp.py プロジェクト: alexeynaumov/qnetwork
class TcpServer(QObject):
    '''
    TCP/IP server class.

    Usage:
        import sys
        import tcp
        from PyQt4.QtCore import QCoreApplication
        from PyQt4.QtNetwork import QHostAddress


        def main():
            application = QCoreApplication(sys.argv)

            tcpServer = tcp.TcpServer()

            def onConnected(descriptor):
                print("Client [%s] connected. Now total: %s" % (descriptor, len(tcpServer.descriptors())))
                tcpServer.write(descriptor, "Hello dude")

            def onDisconnected(descriptor):
                print("Client [%s] disconnected. Now total: %s" % (descriptor, len(tcpServer.descriptors())))

            def onError(descriptor, error):
                print("Error [%s]: ", descriptor, error)

            def onRead(descriptor, data):
                print("Read from [%s] %s byte(s): %s" % (descriptor, len(data), data))

            tcpServer.onConnected = onConnected
            tcpServer.onDisconnected = onDisconnected
            tcpServer.onError = onError
            tcpServer.onRead = onRead
            tcpServer.listen(QHostAddress.Any, 9000)

            sys.exit(application.exec_())

        if __name__ == "__main__":
            main()
    '''
    def __init__(self, parent=None):
        QObject.__init__(self, parent)
        self.__server = QTcpServer(parent)
        self.__clients = dict()  # All active clients

        # Callbacks
        self.__on_connected = None
        self.__on_disconnected = None
        self.__on_error = None
        self.__on_read = None

        # Signals and slots connections
        self.__server.newConnection.connect(self.__onNewConnection)

    # Slots
    @pyqtSlot()
    def __onNewConnection(self):
        '''
        The slot is called every time a client connects to the server. The client's socket(QTcpSocket) <socket> and
        descriptor(int) <descriptor> are defined. The socket is appended to the dictionary of connected
        clients(key=client's descriptor, value=client's socket). Then, socket's descriptor is passed to
        __onConnected method.
        :return: None
        '''

        socket = self.__server.nextPendingConnection()
        socket.disconnected.connect(self.__onDisconnected)
        socket.error.connect(self.__onError)
        socket.readyRead.connect(self.__onReadyRead)
        descriptor = id(socket)
        self.__clients[descriptor] = socket
        self.__onConnected(descriptor)

    @pyqtSlot()
    def __onConnected(self, descriptor):
        '''
        The method is called by __onNewConnection every time a client connects to the server. If __on_connected callback
        is set, it is executed with socket's descriptor(int) <descriptor> argument.
        :param descriptor(int): a newly connected client's socket descriptor, the socket itself is in self.__clients
        dictionary(key=client's descriptor, value=client's socket);
        :return: None
        '''

        if self.__on_connected:
            self.__on_connected(descriptor)

    @pyqtSlot()
    def __onDisconnected(self):
        '''
        The slot is called when the connected client disconnects from the server. The client's socket(QTcpSocket)
        <socket> and its descriptor(int) <descriptor> are defined, and then the descriptor is passed to
        __on_disconnected callback.
        :return: None
        '''

        if self.__on_disconnected:
            socket = self.sender()
            descriptor = id(socket)
            self.__clients.pop(descriptor, None)
            self.__on_disconnected(descriptor)

    @pyqtSlot()
    def __onError(self, socketError):
        '''
        The slot is called when an error(PyQt4.QtNetwork.SocketError) <socketError> occurs. The socket's descriptor(int)
        <descriptor> with error code(int) <errorCode> and description(str) <errorDescription> are defined and passed
        to __on_error callback.
        :param error(QAbstractSocket.SocketError): socket error;
        :return: None
        '''

        if self.__on_error:
            socket = self.__server.sender()
            descriptor = id(socket)
            errorCode = int(socketError)
            errorDescription = str(self.__server.errorString())
            error = (errorCode, errorDescription)

            self.__on_error(descriptor, error)

    @pyqtSlot()
    def __onReadyRead(self):
        '''
        The slot is called when new data is available for reading from the client. The client's socket descriptor(int)
        <descriptor> is defined, and all available data(str) <data> is read. Then, the socket descriptor and the data
        are passed to __on_read callback.
        :return: None
        '''

        if self.__on_read:
            socket = self.sender()
            descriptor = id(socket)
            data = socket.readAll().data()
            self.__on_read(descriptor, data)

    # Setters
    def __connected(self, callback):
        self.__on_connected = callback

    def __disconnected(self, callback):
        self.__on_disconnected = callback

    def __error(self, callback):
        self.__on_error = callback

    def __read(self, callback):
        self.__on_read = callback

    # Methods
    def isListening(self):
        '''
        Return True if the server is currently listening for incoming connections, otherwise returns False.
        :return: bool
        '''

        return self.__server.isListening()

    def listen(self, address=None, port=0):
        '''
        Tell the server to listen for incoming connections on address(QHostAddress) <address> and port(int) <port>. If
        port is 0, a port is chosen automatically. If address is QHostAddress.Any, the server will listen on all network
        interfaces.
        :param address(QHosAddress): address to listen to;
        :param port(int): the port to listen to;
        :return: bool, return True on success, otherwise return False
        '''
        self.__server.listen(address, port)

    def socket(self, descriptor):
        '''
        Return socket(QTcpSocket) with the given descriptor(int) <descriptor> or None if it is not found.
        :param descriptor(int): socket descriptor;
        :return: socket(QTcpSocket) or None
        '''

        return self.__clients.get(descriptor, None)

    def descriptors(self):
        '''
        Return all sockets' descriptors available.
        :return list of int
        '''

        return sorted(self.__clients.keys())

    def write(self, descriptor, data):
        '''
        Write data(str) <data> to the client's socket with the given descriptor(int) <descriptor>.
        :param descriptor(int): client's socket descriptor;
        :param data(str), data to be written;
        :return: int, the number of bytes that were actually written, or -1 if an error occurred
        '''

        socket = self.socket(descriptor)
        if socket:
            return socket.write(data)
        else:
            return -1

    def disconnect(self, descriptor):
        '''
        Disconnect the client socket with the given descriptor(int) <descriptor>.
        :param descriptor(int): client's socket descriptor;
        :return: None
        '''

        socket = self.socket(descriptor)
        if socket:
            socket.close()

    def close(self):
        '''
        Close the server.
        :return: None
        '''
        for socket in self.__clients.values():
            socket.close()

        self.__server.close()

    # Properties
    onConnected = property(fset=__connected)
    onDisconnected = property(fset=__disconnected)
    onError = property(fset=__error)
    onRead = property(fset=__read)
コード例 #12
0
ファイル: loopback.py プロジェクト: death-finger/Scripts
class Dialog(QDialog):
    TotalBytes = 50 * 1024 * 1024
    PayloadSize = 65536

    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)

        self.tcpServer = QTcpServer()
        self.tcpClient = QTcpSocket()
        self.bytesToWrite = 0
        self.bytesWritten = 0
        self.bytesReceived = 0

        self.clientProgressBar = QProgressBar()
        self.clientStatusLabel = QLabel("Client ready")
        self.serverProgressBar = QProgressBar()
        self.serverStatusLabel = QLabel("Server ready")

        self.startButton = QPushButton("&Start")
        self.quitButton = QPushButton("&Quit")

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

        self.startButton.clicked.connect(self.start)
        self.quitButton.clicked.connect(self.close)
        self.tcpServer.newConnection.connect(self.acceptConnection)
        self.tcpClient.connected.connect(self.startTransfer)
        self.tcpClient.bytesWritten.connect(self.updateClientProgress)
        self.tcpClient.error.connect(self.displayError)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.clientProgressBar)
        mainLayout.addWidget(self.clientStatusLabel)
        mainLayout.addWidget(self.serverProgressBar)
        mainLayout.addWidget(self.serverStatusLabel)
        mainLayout.addStretch(1)
        mainLayout.addSpacing(10)
        mainLayout.addWidget(buttonBox)
        self.setLayout(mainLayout)

        self.setWindowTitle("Loopback")

    def start(self):
        self.startButton.setEnabled(False)

        QApplication.setOverrideCursor(Qt.WaitCursor)

        self.bytesWritten = 0
        self.bytesReceived = 0

        while not self.tcpServer.isListening() and not self.tcpServer.listen():
            ret = QMessageBox.critical(self, "Loopback",
                    "Unable to start the test: %s." % self.tcpServer.errorString(),
                    QMessageBox.Retry | QMessageBox.Cancel)
            if ret == QMessageBox.Cancel:
                return

        self.serverStatusLabel.setText("Listening")
        self.clientStatusLabel.setText("Connecting")

        self.tcpClient.connectToHost(QHostAddress(QHostAddress.LocalHost), self.tcpServer.serverPort())

    def acceptConnection(self):
        self.tcpServerConnection = self.tcpServer.nextPendingConnection()
        self.tcpServerConnection.readyRead.connect(self.updateServerProgress)
        self.tcpServerConnection.error.connect(self.displayError)

        self.serverStatusLabel.setText("Accepted connection")
        self.tcpServer.close()

    def startTransfer(self):
        self.bytesToWrite = Dialog.TotalBytes - self.tcpClient.write(QByteArray(Dialog.PayloadSize, '@'))
        self.clientStatusLabel.setText("Connected")

    def updateServerProgress(self):
        self.bytesReceived += self.tcpServerConnection.bytesAvailable()
        self.tcpServerConnection.readAll()

        self.serverProgressBar.setMaximum(Dialog.TotalBytes)
        self.serverProgressBar.setValue(self.bytesReceived)
        self.serverStatusLabel.setText("Received %dMB" % (self.bytesReceived / (1024 * 1024)))

        if self.bytesReceived == Dialog.TotalBytes:
            self.tcpServerConnection.close()
            self.startButton.setEnabled(True)
            QApplication.restoreOverrideCursor()

    def updateClientProgress(self, numBytes):
        self.bytesWritten += numBytes
        if self.bytesToWrite > 0:
            self.bytesToWrite -= self.tcpClient.write(QByteArray(
                                        min(self.bytesToWrite, Dialog.PayloadSize), '@'))

        self.clientProgressBar.setMaximum(Dialog.TotalBytes)
        self.clientProgressBar.setValue(self.bytesWritten)
        self.clientStatusLabel.setText("Sent %dMB" % (self.bytesWritten / (1024 * 1024)))

    def displayError(self, socketError):
        if socketError == QTcpSocket.RemoteHostClosedError:
            return

        QMessageBox.information(self, "Network error",
                "The following error occured: %s." % self.tcpClient.errorString())

        self.tcpClient.close()
        self.tcpServer.close()
        self.clientProgressBar.reset()
        self.serverProgressBar.reset()
        self.clientStatusLabel.setText("Client ready")
        self.serverStatusLabel.setText("Server ready")
        self.startButton.setEnabled(True)
        QApplication.restoreOverrideCursor()
コード例 #13
0
class Dialog(QDialog):
    def __init__(self, parent: QWidget = None) -> None:
        super().__init__(parent)

        self.tcpServer = QTcpServer()
        self.tcpClient = QTcpSocket()
        self.tcpServerConnection: QTcpSocket = None

        self.bytesToWrite = 0
        self.bytesWritten = 0
        self.bytesReceived = 0

        self.clientProgressBar = QProgressBar()
        self.clientStatusLabel = QLabel(self.tr("Client ready"))
        self.serverProgressBar = QProgressBar()
        self.serverStatusLabel = QLabel(self.tr("Server ready"))

        self.startButton = QPushButton(self.tr("&Start"))
        self.quitButton = QPushButton(self.tr("&Quit"))

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

        self.startButton.clicked.connect(self.start)
        self.quitButton.clicked.connect(self.close)
        self.tcpServer.newConnection.connect(self.acceptConnection)
        self.tcpClient.connected.connect(self.startTransfer)
        self.tcpClient.bytesWritten.connect(self.updateClientProgress)
        self.tcpClient.error.connect(self.displayError)

        mainLayout = QVBoxLayout(self)
        mainLayout.addWidget(self.clientProgressBar)
        mainLayout.addWidget(self.clientStatusLabel)
        mainLayout.addWidget(self.serverProgressBar)
        mainLayout.addWidget(self.serverStatusLabel)
        mainLayout.addStretch(1)
        mainLayout.addSpacing(10)
        mainLayout.addWidget(self.buttonBox)

    @pyqtSlot()
    def start(self):
        self.startButton.setEnabled(False)

        QGuiApplication.setOverrideCursor(Qt.WaitCursor)

        self.bytesWritten = 0
        self.bytesReceived = 0

        while not self.tcpServer.isListening() and not self.tcpServer.listen():
            ret = QMessageBox.critical(
                self,
                self.tr("Loopback"),
                self.tr(
                    "Unable to start the test: %s" % (self.tcpServer.errorString())
                ),
                QMessageBox.Retry | QMessageBox.Cancel,
            )
            if ret == QMessageBox.Cancel:
                return

        self.serverStatusLabel.setText(self.tr("Listening"))
        self.clientStatusLabel.setText(self.tr("Connecting"))
        self.tcpClient.connectToHost(
            QHostAddress.LocalHost, self.tcpServer.serverPort()
        )

    @pyqtSlot()
    def acceptConnection(self):
        self.tcpServerConnection = self.tcpServer.nextPendingConnection()
        if not self.tcpServerConnection:
            self.serverStatusLabel.setText(
                self.tr("Error: got invalid pending connection!")
            )
            return

        self.tcpServerConnection.readyRead.connect(self.updateServerProgress)
        self.tcpServerConnection.error.connect(self.displayError)
        self.tcpServerConnection.disconnected.connect(
            self.tcpServerConnection.deleteLater
        )

        self.serverStatusLabel.setText(self.tr("Accepted connection"))
        self.tcpServer.close()

    @pyqtSlot()
    def startTransfer(self):
        # called when the TCP client connected to the loopback server
        self.bytesToWrite = TOTAL_BYTES - int(
            self.tcpClient.write(QByteArray(PAYLOAD_SIZE, "@"))
        )
        self.clientStatusLabel.setText(self.tr("Connected"))

    @pyqtSlot()
    def updateServerProgress(self):
        self.bytesReceived += int(self.tcpServerConnection.bytesAvailable())
        self.tcpServerConnection.readAll()

        self.serverProgressBar.setMaximum(TOTAL_BYTES)
        self.serverProgressBar.setValue(self.bytesReceived)
        self.serverStatusLabel.setText(
            self.tr("Received %dMB" % (self.bytesReceived / (1024 * 1024),))
        )

        if self.bytesReceived == TOTAL_BYTES:
            self.tcpServerConnection.close()
            self.startButton.setEnabled(True)

            QGuiApplication.restoreOverrideCursor()

    @pyqtSlot("qint64")
    def updateClientProgress(self, numBytes):
        self.bytesWritten += int(numBytes)

        if self.bytesToWrite > 0 and self.tcpClient.bytesToWrite() <= 4 * PAYLOAD_SIZE:
            self.bytesToWrite -= self.tcpClient.write(
                QByteArray(min(self.bytesToWrite, PAYLOAD_SIZE), "@")
            )

        self.clientProgressBar.setMaximum(TOTAL_BYTES)
        self.clientProgressBar.setValue(self.bytesWritten)
        self.clientStatusLabel.setText(
            self.tr("Sent %dMB" % (self.bytesWritten / (1024 * 1024),))
        )

    @pyqtSlot(QAbstractSocket.SocketError)
    def displayError(self, socketError):
        if socketError == QTcpSocket.RemoteHostClosedError:
            return

        QMessageBox.information(
            self,
            self.tr("Network error"),
            self.tr(
                "The following error occurred: %s." % (self.tcpClient.errorString(),)
            ),
        )
        self.tcpClient.close()
        self.tcpServer.close()
        self.clientProgressBar.reset()
        self.serverProgressBar.reset()
        self.clientStatusLabel.setText(self.tr("Client ready"))
        self.serverStatusLabel.setText(self.tr("Server ready"))
        self.startButton.setEnabled(True)
        QGuiApplication.restoreOverrideCursor()
コード例 #14
0
class CodeExecutor(object):
    """
    This class is responsible for executing code (when starting Tribler in debug mode).
    The protocol to execute code is as follows.
    First, a client that wants to execute some code opens a connection with the TCP server and sends the
    string: <code in base64 format> <task_id>\n
    This code will be executed and the result will be sent to the client in the following format:
    result <result> <task_id>\n.
    If Tribler crashes, the server sends the following result: crash <stack trace in base64 format>

    Note that the socket uses the newline as separator.
    """
    def __init__(self, port, shell_variables={}):
        self.logger = logging.getLogger(self.__class__.__name__)
        self.tcp_server = QTcpServer()
        self.sockets = []
        self.stack_trace = None
        if not self.tcp_server.listen(port=port):
            self.logger.error(
                "Unable to start code execution socket! Error: %s",
                self.tcp_server.errorString())
        else:
            self.tcp_server.newConnection.connect(self._on_new_connection)

        self.shell = Console(locals=shell_variables)

    def _on_new_connection(self):
        while self.tcp_server.hasPendingConnections():
            socket = self.tcp_server.nextPendingConnection()
            socket.readyRead.connect(self._on_socket_read_ready)
            socket.disconnected.connect(
                lambda dc_socket=socket: self._on_socket_disconnect(dc_socket))
            self.sockets.append(socket)

            # If Tribler has crashed, notify the other side immediately
            if self.stack_trace:
                self.on_crash(self.stack_trace)

    def run_code(self, code, task_id):
        self.shell.runcode(code)
        stdout = self.shell.stdout.read()
        stderr = self.shell.stderr.read()

        self.logger.info("Code execution with task %s finished:", task_id)
        self.logger.info("Stdout of task %s: %s", task_id, stdout)
        if 'Traceback' in stderr and 'SystemExit' not in stderr:
            self.logger.error("Executed code with failure: %s",
                              b64encode(code))

        # Determine the return value
        if 'return_value' not in self.shell.console.locals:
            return_value = ''.encode('base64')
        else:
            return_value = str(
                self.shell.console.locals['return_value']).encode('base64')

        for socket in self.sockets:
            socket.write("result %s %s\n" % (return_value, task_id))

    def on_crash(self, exception_text):
        self.stack_trace = exception_text
        for socket in self.sockets:
            socket.write("crash %s\n" % exception_text.encode('base64'))

    def _on_socket_read_ready(self):
        data = str(self.sockets[0].readAll())
        parts = data.split(" ")
        if len(parts) != 2:
            return

        try:
            code = parts[0].decode('base64')
            task_id = parts[1].replace('\n', '')
            self.run_code(code, task_id)
        except binascii.Error:
            self.logger.error("Invalid base64 code string received!")

    def _on_socket_disconnect(self, socket):
        self.sockets.remove(socket)
コード例 #15
0
ファイル: code_executor.py プロジェクト: Tribler/tribler
class CodeExecutor(object):
    """
    This class is responsible for executing code (when starting Tribler in debug mode).
    The protocol to execute code is as follows.
    First, a client that wants to execute some code opens a connection with the TCP server and sends the
    string: <code in base64 format> <task_id>\n
    This code will be executed and the result will be sent to the client in the following format:
    result <result> <task_id>\n.
    If Tribler crashes, the server sends the following result: crash <stack trace in base64 format>

    Note that the socket uses the newline as separator.
    """

    def __init__(self, port, shell_variables={}):
        self.logger = logging.getLogger(self.__class__.__name__)
        self.tcp_server = QTcpServer()
        self.sockets = []
        self.stack_trace = None
        if not self.tcp_server.listen(port=port):
            self.logger.error("Unable to start code execution socket! Error: %s", self.tcp_server.errorString())
        else:
            self.tcp_server.newConnection.connect(self._on_new_connection)

        self.shell = Console(locals=shell_variables)

    def _on_new_connection(self):
        while self.tcp_server.hasPendingConnections():
            socket = self.tcp_server.nextPendingConnection()
            socket.readyRead.connect(self._on_socket_read_ready)
            socket.disconnected.connect(lambda dc_socket=socket: self._on_socket_disconnect(dc_socket))
            self.sockets.append(socket)

            # If Tribler has crashed, notify the other side immediately
            if self.stack_trace:
                self.on_crash(self.stack_trace)

    def run_code(self, code, task_id):
        self.shell.runcode(code)
        stdout = self.shell.stdout.read()
        stderr = self.shell.stderr.read()

        self.logger.info("Code execution with task %s finished:", task_id)
        self.logger.info("Stdout of task %s: %s", task_id, stdout)
        if 'Traceback' in stderr and 'SystemExit' not in stderr:
            self.logger.error("Executed code with failure: %s", b64encode(code))

        # Determine the return value
        if 'return_value' not in self.shell.console.locals:
            return_value = ''.encode('base64')
        else:
            return_value = str(self.shell.console.locals['return_value']).encode('base64')

        for socket in self.sockets:
            socket.write("result %s %s\n" % (return_value, task_id))

    def on_crash(self, exception_text):
        self.stack_trace = exception_text
        for socket in self.sockets:
            socket.write("crash %s\n" % exception_text.encode('base64'))

    def _on_socket_read_ready(self):
        data = str(self.sockets[0].readAll())
        parts = data.split(" ")
        if len(parts) != 2:
            return

        try:
            code = parts[0].decode('base64')
            task_id = parts[1].replace('\n', '')
            self.run_code(code, task_id)
        except binascii.Error:
            self.logger.error("Invalid base64 code string received!")

    def _on_socket_disconnect(self, socket):
        self.sockets.remove(socket)