【问题标题】:PyQt5: Sending and receiving messages between client and serverPyQt5:在客户端和服务器之间发送和接收消息
【发布时间】:2017-05-01 05:56:34
【问题描述】:

我正在尝试创建一个服务器和客户端来发送和接收消息。我的问题是在客户端和服务器之间发送和接收。

client.py

from PyQt5.QtCore import QIODevice
from PyQt5.QtWidgets import QApplication, QDialog
from PyQt5.QtNetwork import QTcpSocket

class Client(QDialog):
    def __init__(self):
        super().__init__()
        HOST = '127.0.0.1'
        PORT = 8000
        self.tcpSocket = QTcpSocket(self)
        self.tcpSocket.connectToHost(HOST, PORT, QIODevice.ReadWrite)
        self.tcpSocket.readyRead.connect(self.dealCommunication)
        self.tcpSocket.error.connect(self.displayError)

    def dealCommunication(self):
        print("connected !\n")
        # i want here to send and receive messages

    def displayError(self):
        print(self, "The following error occurred: %s." % self.tcpSocket.errorString())

if __name__ == '__main__':

    import sys
    app = QApplication(sys.argv)
    client = Client()
    sys.exit(client.exec_())

server.py

import sys
from PyQt5.QtCore import QByteArray, QDataStream, QIODevice
from PyQt5.QtWidgets import QApplication, QDialog
from PyQt5.QtNetwork import QHostAddress, QTcpServer, QTcpSocket

class Server(QDialog, QTcpSocket):
    def __init__(self):
        super().__init__()
        self.tcpServer = None

    def sessionOpened(self):
        self.tcpServer = QTcpServer(self)
        PORT = 8000
        address = QHostAddress('127.0.0.1')
        self.tcpServer.listen(address, PORT)
        self.tcpServer.newConnection.connect(self.dealCommunication)

    def dealCommunication(self):
        # i want here to send and receive messages 
        data = input()
        block = QByteArray()
        out = QDataStream(block, QIODevice.ReadWrite)
        out.writeQString(data)
        clientConnection = self.tcpServer.nextPendingConnection()
        clientConnection.write(block)
        clientConnection.disconnectFromHost()

if __name__ == '__main__':

    app = QApplication(sys.argv)
    server = Server()
    server.sessionOpened()
    sys.exit(server.exec_())

我已经搜索过,但我很困惑。我找到了一些代码,但我不明白它到底是做什么的:

data = input()
block = QByteArray()
out = QDataStream(block, QIODevice.ReadWrite)
out.writeQString(data)
clientConnection = self.tcpServer.nextPendingConnection()
clientConnection.write(block)
clientConnection.disconnectFromHost()

【问题讨论】:

  • 你的问题到底是什么?
  • 我想在client.py和server.py之间收发短信

标签: python pyqt pyqt5 qtcpsocket qtcpserver


【解决方案1】:

client.py

from PyQt5.QtCore import QDataStream, QIODevice
from PyQt5.QtWidgets import QApplication, QDialog
from PyQt5.QtNetwork import QTcpSocket, QAbstractSocket

class Client(QDialog):
    def __init__(self):
        super().__init__()
        self.tcpSocket = QTcpSocket(self)
        self.blockSize = 0
        self.makeRequest()
        self.tcpSocket.waitForConnected(1000)
        # send any message you like it could come from a widget text.
        self.tcpSocket.write(b'hello')
        self.tcpSocket.readyRead.connect(self.dealCommunication)
        self.tcpSocket.error.connect(self.displayError)

    def makeRequest(self):
        HOST = '127.0.0.1'
        PORT = 8000
        self.tcpSocket.connectToHost(HOST, PORT, QIODevice.ReadWrite)

    def dealCommunication(self):
        instr = QDataStream(self.tcpSocket)
        instr.setVersion(QDataStream.Qt_5_0)
        if self.blockSize == 0:
            if self.tcpSocket.bytesAvailable() < 2:
                return
            self.blockSize = instr.readUInt16()
        if self.tcpSocket.bytesAvailable() < self.blockSize:
            return
        # Print response to terminal, we could use it anywhere else we wanted.
        print(str(instr.readString(), encoding='ascii'))

    def displayError(self, socketError):
        if socketError == QAbstractSocket.RemoteHostClosedError:
            pass
        else:
            print(self, "The following error occurred: %s." % self.tcpSocket.errorString())


if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    client = Client()
    sys.exit(client.exec_())

server.py

import sys
from PyQt5.QtCore import QByteArray, QDataStream, QIODevice
from PyQt5.QtWidgets import QApplication, QDialog
from PyQt5.QtNetwork import QHostAddress, QTcpServer

class Server(QDialog):
    def __init__(self):
        super().__init__()
        self.tcpServer = None

    def sessionOpened(self):
        self.tcpServer = QTcpServer(self)
        PORT = 8000
        address = QHostAddress('127.0.0.1')
        if not self.tcpServer.listen(address, PORT):
            print("cant listen!")
            self.close()
            return
        self.tcpServer.newConnection.connect(self.dealCommunication)

    def dealCommunication(self):
        # Get a QTcpSocket from the QTcpServer
        clientConnection = self.tcpServer.nextPendingConnection()
        # instantiate a QByteArray
        block = QByteArray()
        # QDataStream class provides serialization of binary data to a QIODevice
        out = QDataStream(block, QIODevice.ReadWrite)
        # We are using PyQt5 so set the QDataStream version accordingly.
        out.setVersion(QDataStream.Qt_5_0)
        out.writeUInt16(0)
        # this is the message we will send it could come from a widget.
        message = "Goodbye!"
        # get a byte array of the message encoded appropriately.
        message = bytes(message, encoding='ascii')
        # now use the QDataStream and write the byte array to it.
        out.writeString(message)
        out.device().seek(0)
        out.writeUInt16(block.size() - 2)
        # wait until the connection is ready to read
        clientConnection.waitForReadyRead()
        # read incomming data
        instr = clientConnection.readAll()
        # in this case we print to the terminal could update text of a widget if we wanted.
        print(str(instr, encoding='ascii'))
        # get the connection ready for clean up
        clientConnection.disconnected.connect(clientConnection.deleteLater)
        # now send the QByteArray.
        clientConnection.write(block)
        # now disconnect connection.
        clientConnection.disconnectFromHost()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    server = Server()
    server.sessionOpened()
    sys.exit(server.exec_())

它带有非常有限的错误处理,但向您展示了基础知识。

已编辑以解释您想要解释的代码

【讨论】:

  • 非常感谢。但是让它像聊天而不仅仅是一条消息呢?消息 = 输入()
  • 实现聊天服务器超出了问题的范围。但是首先,您不能使用您拥有的代码向客户端推送 - 客户端连接发送消息并接收消息。如果您有两个客户端实例,则可以让它们通过服务器聊天。您需要添加 QTextEdit QLabel 和 QPushButton 并将请求代码链接到按钮并使用响应更新 QLabel。然后,您需要在服务器上进行某种路由,以便在下一个请求时将一个客户端消息路由到另一个客户端。然后你需要让客户端轮询服务器。
  • 但我想我回答了你原来的问题。
  • 是的,这只是一个问题。我将其标记为答案,非常感谢兄弟。
猜你喜欢
  • 2015-11-09
  • 2021-03-05
  • 2021-12-23
  • 1970-01-01
  • 2022-11-29
  • 1970-01-01
  • 2023-01-07
  • 1970-01-01
  • 2016-09-03
相关资源
最近更新 更多