Python QTcpSocket и QTcpServer получают сообщение - PullRequest
0 голосов
/ 03 апреля 2019

Я не совсем уверен, почему мое приложение не получает сообщение, которое ему отправляется. Похоже, сообщение отправляется. Я посмотрел на этот пример в качестве ссылки.

как прослушать определенный порт в qt с помощью QTcpSocket?

Я также пытался преобразовать этот пример c ++, и он, похоже, не отправлял никаких сообщений, как ожидалось: QTcpSocket: чтение и запись

Полученное сообщение должно быть напечатано на консоли, однако полученные байты всегда возвращают 0.

import sys
from PyQt4 import QtNetwork, QtCore, QtGui

class Messenger(object):
    def __init__(self):
        super(Messenger, self).__init__()
        self.TCP_HOST = '127.0.0.1' # QtNetwork.QHostAddress.LocalHost
        self.TCP_SEND_TO_PORT = 7011
        self.pSocket = None
        self.listenServer = None

    def slotSendMessage(self):
        self.pSocket = QtNetwork.QTcpSocket();
        self.pSocket.readyRead.connect(self.slotReadData)
        self.pSocket.connectToHost(self.TCP_HOST, self.TCP_SEND_TO_PORT)

        if not (self.pSocket.waitForConnected(1000)): # one second
            print 'Unable to send data to port: "{}"'.format(self.TCP_SEND_TO_PORT)
            return

        cmd = "Hi there!"
        print 'Command Sent:', cmd
        ucmd = unicode(cmd, "utf-8")
        self.pSocket.write(ucmd)
        self.pSocket.waitForBytesWritten(1000)

        # Do something with readData
        self.pSocket.disconnectFromHost()
        self.pSocket.waitForDisconnected(1000)


    def slotReadData(self):
        print 'Reading data:', self.pSocket.readAll()
        # QByteArray data = pSocket->readAll();


class Client(QtCore.QObject):
    def __init__(self, parent=None):
        QtCore.QObject.__init__(self)

    def SetSocket(self, Descriptor):
        self.socket = QtNetwork.QTcpSocket(self)
        self.connect(self.socket, QtCore.SIGNAL("connected()"), QtCore.SLOT(self.connected()))
        self.connect(self.socket, QtCore.SIGNAL("disconnected()"), QtCore.SLOT(self.disconnected()))
        self.connect(self.socket, QtCore.SIGNAL("readyRead()"), QtCore.SLOT(self.readyRead()))

        self.socket.setSocketDescriptor(Descriptor)
        print "Client Connected from IP %s" % self.socket.peerAddress().toString()

    def connected(self):
        print "Client Connected Event"

    def disconnected(self):
        print "Client Disconnected"

    def readyRead(self):
        msg = self.socket.readAll()
        print type(msg), msg.count()
        print "Client Message:", msg


class Server(QtCore.QObject):
    def __init__(self, parent=None):
        QtCore.QObject.__init__(self)
        self.TCP_LISTEN_TO_PORT = 7011


    def incomingConnection(self, handle):
        print "Incoming Connection..."
        self.client = Client(self)
        self.client.SetSocket(handle)

    def StartServer(self):
        self.server = QtNetwork.QTcpServer()
        self.server.incomingConnection = self.incomingConnection
        if self.server.listen(QtNetwork.QHostAddress.Any, self.TCP_LISTEN_TO_PORT):
            print "Server is listening on port: {}".format(self.TCP_LISTEN_TO_PORT)    
        else:
            print "Server couldn't wake up"


class Example(QtGui.QMainWindow):

    def __init__(self):
        super(Example, self).__init__()
        self.setWindowTitle('TCP/Server')
        self.resize(300, 300)

        self.uiConnect =QtGui.QPushButton('Connect')

        # layout
        self.layout = QtGui.QVBoxLayout()
        self.layout.addWidget(self.uiConnect)
        self.widget = QtGui.QWidget()
        self.widget.setLayout(self.layout)
        self.setCentralWidget(self.widget)

        # Connections
        self.uiConnect.clicked.connect(self.setup)


    def setup(self):
        server = Server()
        server.StartServer()

        tcp = Messenger()
        tcp.slotSendMessage()


def main():

    app = QtGui.QApplication(sys.argv)
    ex = Example()
    ex.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

1 Ответ

1 голос
/ 20 апреля 2019

Вы допускаете следующие ошибки:

  • Вы не должны использовать методы waitForXXX, так как они блокируют, предотвращая выполнение цикла событий, и, следовательно, слоты, подключенные к сигналам, не вызываются.

  • Нет необходимости делать self.server.incomingConnection = self.incomingConnection, это все равно, что перезаписывать класс без использования наследования, чтобы вы могли генерировать проблемы, вместо этого используйте сигнал newConnection, который указывает, когда существует новое соединение, и используйте nextPendingConnection () для получить сокет.

Учитывая вышеизложенное, решение:

import sys
from PyQt4 import QtCore, QtGui, QtNetwork 


class Messenger(object):
    def __init__(self):
        super(Messenger, self).__init__()
        self.TCP_HOST = "127.0.0.1"  # QtNetwork.QHostAddress.LocalHost
        self.TCP_SEND_TO_PORT = 7011
        self.pSocket = None
        self.listenServer = None
        self.pSocket = QtNetwork.QTcpSocket()
        self.pSocket.readyRead.connect(self.slotReadData)
        self.pSocket.connected.connect(self.on_connected)
        self.pSocket.error.connect(self.on_error)

    def slotSendMessage(self):
        self.pSocket.connectToHost(self.TCP_HOST, self.TCP_SEND_TO_PORT)

    def on_error(self, error):
        if error == QtNetwork.QAbstractSocket.ConnectionRefusedError:
            print(
                'Unable to send data to port: "{}"'.format(
                    self.TCP_SEND_TO_PORT
                )
            )
            print("trying to reconnect")
            QtCore.QTimer.singleShot(1000, self.slotSendMessage)

    def on_connected(self):
        cmd = "Hi there!"
        print("Command Sent:", cmd)
        ucmd = unicode(cmd, "utf-8")
        self.pSocket.write(ucmd)
        self.pSocket.flush()
        self.pSocket.disconnectFromHost()

    def slotReadData(self):
        print("Reading data:", self.pSocket.readAll())
        # QByteArray data = pSocket->readAll();


class Client(QtCore.QObject):
    def SetSocket(self, socket):
        self.socket = socket
        self.socket.connected.connect(self.on_connected)
        self.socket.disconnected.connect(self.on_connected)
        self.socket.readyRead.connect(self.on_readyRead)
        print(
            "Client Connected from IP %s" % self.socket.peerAddress().toString()
        )

    def on_connected(self):
        print("Client Connected Event")

    def on_disconnected(self):
        print("Client Disconnected")

    def on_readyRead(self):
        msg = self.socket.readAll()
        print(type(msg), msg.count())
        print("Client Message:", msg)


class Server(QtCore.QObject):
    def __init__(self, parent=None):
        QtCore.QObject.__init__(self)
        self.TCP_LISTEN_TO_PORT = 7011
        self.server = QtNetwork.QTcpServer()
        self.server.newConnection.connect(self.on_newConnection)

    def on_newConnection(self):
        while self.server.hasPendingConnections():
            print("Incoming Connection...")
            self.client = Client(self)
            self.client.SetSocket(self.server.nextPendingConnection())

    def StartServer(self):
        if self.server.listen(
            QtNetwork.QHostAddress.Any, self.TCP_LISTEN_TO_PORT
        ):
            print(
                "Server is listening on port: {}".format(
                    self.TCP_LISTEN_TO_PORT
                )
            )
        else:
            print("Server couldn't wake up")


class Example(QtGui.QMainWindow):
    def __init__(self):
        super(Example, self).__init__()
        self.setWindowTitle("TCP/Server")
        self.resize(300, 300)

        self.uiConnect = QtGui.QPushButton("Connect")

        # layout
        self.layout = QtGui.QVBoxLayout()
        self.layout.addWidget(self.uiConnect)
        self.widget = QtGui.QWidget()
        self.widget.setLayout(self.layout)
        self.setCentralWidget(self.widget)

        # Connections
        self.uiConnect.clicked.connect(self.setup)

    def setup(self):
        self.server = Server()
        self.server.StartServer()

        self.tcp = Messenger()
        self.tcp.slotSendMessage()


def main():

    app = QtGui.QApplication(sys.argv)
    ex = Example()
    ex.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
...