本文介绍了Python QTcpSocket 和 QTcpServer 接收消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不太确定为什么我的应用程序没有收到发送给它的消息.看来消息正在发送.我看这个例子作为参考.

I'm not quite sure why my application does not receive the message that is being sent to it. It appears the message is being sent. I looked at this example as reference.

如何监听特定端口在qt中使用QTcpSocket?

我也尝试转换这个 c++ 示例,但它似乎没有按预期发送任何消息:QTcpSocket:读写

I tried converting this c++ example as well and it didn't seem to send any messages as expected: QTcpSocket: reading and writing

接收到的消息应该打印到控制台,但是接收到的字节总是返回 0.

The message being received should be printed to the console, however the bytes received always return 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()

推荐答案

你犯了以下错误:

  • 您不应该使用 waitForXXX 方法,因为它们会阻塞,阻止事件循环执行,因此不会调用连接到信号的插槽.

  • You should not use the waitForXXX methods since they are blocking, preventing the eventloop from executing and consequently the slots connected to the signals are not invoked.

没有必要做self.server.incomingConnection = self.incomingConnection,这就像不使用继承覆盖类所以你会产生问题,而是使用信号newConnection指示何时有新连接并使用 nextPendingConnection() 获取套接字.

It is not necessary to do self.server.incomingConnection = self.incomingConnection, it is like overwriting the class without using inheritance so you can generate problems, instead use the signal newConnection that indicates when there is a new connection and use nextPendingConnection() to get the socket.

综合以上,解决办法是:

Considering the above, the solution is:

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()

这篇关于Python QTcpSocket 和 QTcpServer 接收消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 12:28