【问题标题】:QTcpSocket readyRead not emittedQTcpSocket readyRead 未发出
【发布时间】:2019-05-31 17:19:08
【问题描述】:

目标是不断地从另一个 tcp 服务器接收一些消息。而不是python内置的tcp套接字,我切换到QTcpsocket。服务器端确认客户端连接。好吧,readyRead 似乎从未发出过,也不知道出了什么问题。

我试过python内置的socket,效果很好。

import socket
import sys
import struct
import json
import os

#crate a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

#Connect the socket to the port where the server is listening
server_address = ('localhost', 3336)
print('connectiong to {} port {}'.format(*server_address))
sock.connect(server_address)


file_count = 0
try:
    amount_received = 0
    amount_expected = 6000
    while amount_received < amount_expected:
        data = sock.recv(5000)
        data_string = data.decode("utf-8")
        #print('received {!r}'.format(data))
        if data_string.find("Header") != -1:
            dataChunkSize = int(data_string[data_string.find("Header")+6:data_string.find("|")])
            print(dataChunkSize)

        try:
            out = json.loads(data_string[data_string.find("JSONSTART|")+10 : data_string.find("JSONEND")])
            print(out)
            file_count += 1
            json_data_folder = "XXXX"
            if os.path.exists(json_data_folder):
                json_data_folder = os.path.join(json_data_folder, str(file_count)+'.json')
                with open(json_data_folder, 'w') as outfile:
                    json.dump(out, outfile, sort_keys=True)
                    print("save")
        except ValueError as e:
            print(e)
            data_false = data
        amount_expected += len(data)

finally:
    print('socket closed')
    sock.close()


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 = 'localhost'
        PORT = 3336
        self.tcpSocket.connectToHost(HOST, PORT, QIODevice.ReadWrite)

    def dealCommunication(self):
        print('Message Comming')
        #data = self.tcpSocket.readAll()
        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='utf-8'))

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

QTcpSocket 客户端应该不断接收输入。

【问题讨论】:

  • 你已经放了两次客户端代码,你有服务器代码吗?
  • @eyllaesc 感谢编辑。第一部分代码应该是python内置代码的试用版,我错误地发布了两次。不,服务器代码不可用,但内置套接字的试用版效果很好。
  • 你用的是什么服务器?
  • @eyllanesc 服务器为win32桌面应用,提供固定端口输出流。
  • 删除self.tcpSocket.waitForConnected(1000)

标签: python pyqt pyqt5 tcpclient


【解决方案1】:

你必须删除:

self.tcpSocket.waitForConnected (1000)

在 Qt 中,waitForXXX(...) 方法是阻塞的。

什么是 Qt 中的阻塞? 它是一个不允许Qt eventloop被执行的任务,从而阻止了异步任务的执行。

这会干扰由 readyRead 触发的数据接收任务,该信号是一个异步元素。

总之,如果要使用事件循环,请不要使用waitForXXX(...) 函数。

【讨论】:

    猜你喜欢
    • 2018-03-24
    • 1970-01-01
    • 1970-01-01
    • 2017-06-23
    • 1970-01-01
    • 2015-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多