1

我有一个显示表格、计算数据等的 QWidget TableView 类...

在它的构造函数中,我启动了该类的 FortuneServer 服务器:

FortuneServer::FortuneServer(QObject *parent)
    : QTcpServer(parent)
{
...

此类在 FortuneServer::incomingConnection 上启动一个新线程,如下所示:

FortuneThread::FortuneThread(int socketDescriptor, const QString &fortune, QObject     *parent)
: QThread(parent), socketDescriptor(socketDescriptor), text(fortune)
{
}

void FortuneThread::run()
{
    QTcpSocket tcpSocket;
    if (!tcpSocket.setSocketDescriptor(socketDescriptor)) {
        emit error(tcpSocket.error());
        cout<<"socket error"<<endl;
        return;
    }
    tcpSocket.waitForReadyRead(10000);
    // this where sockets opens and waits for incoming data...

我需要执行以下操作:

  1. 我需要连接从客户端在此线程中获得的字符串,与 TableView 类中的某个函数计算另一个字符串并将其返回到该线程并将其发送到客户端。

  2. 如果我从线程使用发射,我如何让线程等待结果?

这是如何正确完成的?

4

2 回答 2

3

从网络上的源读取字节时,您可以:

1-使用固定长度的二进制消息。所以你可以等待字节块被读取并做任何你需要做的事情。2- 使用基于字符串的协议,该协议使用分隔符来分隔消息。当看到分隔符时,您需要提取新的收入消息。3- 使用 Content Length 之类的东西来了解有多少字节来了,你应该阅读。

在 Qt 中,您需要slotCalled类中有一个。以及Callersignal中的一个。当一个新字符串到达​​时(使用任何方法),您只需发出信号,被调用的类就会得到通知。您必须使用方法将插槽连接到信号。我认为which is a parent for有一个名为 readyRead() 的信号,当有新数据可用时,它会为您提供信号。connect()QIODeviceQTcpSocket

永远不要做可能在构造函数中抛出异常的操作。最好以不同的方法从构造函数中创建和启动服务器。

于 2012-06-10T03:16:39.507 回答
2

我认为最好的方法不是启动一个单独的线程,而是将你的 socketDescriptor int 提供给一个 QSocketNotifier 对象(类型为 QSocketNotifier::Read)并将 QSocketNotifier 的 activate(int) 信号连接到你的 GUI 中的一个插槽班级。然后,每当字节准备好从网络读取时,您的插槽将在主线程中被调用,您可以在那里读取它们并处理它们,而无需处理线程间消息传递或信令或阻塞问题。这样容易得多:)

于 2012-06-10T03:22:45.377 回答