Python QTcpSocket和QTcpServer接收消息

时间:2019-04-03 11:47:53

标签: python tcp pyqt pyqt4

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

how to listen to a specific port in qt using QTcpSocket?

我也尝试转换此c ++示例,但似乎未按预期发送任何消息:QTcpSocket: reading and writing

应该将接收到的消息打印到控制台,但是接收到的字节总是返回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 个答案:

答案 0 :(得分:1)

您犯了以下错误:

  • 您不应该使用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()