【问题标题】:QT readReady() TCPSocket no recieving message until after it is neededQT read Ready() TCP Socket 在需要之前不接收消息
【发布时间】:2013-12-26 00:40:25
【问题描述】:

这是家庭作业,所以只是一些概念性提示会很好。

在我创建客户端服务器项目的那一刻,客户端将向服务器发送一条消息(这部分效果很好),但随后服务器将一条消息发送回客户端,这就是我开始遇到问题的地方,我在我的客户端中创建了一个名为 Connection Management 的单独类,用于处理发送接收消息,这个类由我的 Controller 类使用,它处理我所有 UI 页面的应用程序逻辑,现在当我的控制器发送消息时向服务器发回一条消息,atm 我将它作为回显,我的 ConnectionManagement 类使用 readyRead() 信号处理传入消息,这里的问题是当有人使用我的客户端并说按下下一个按钮,下一个按钮插槽将被调用,并等到执行 NextButtonPressed() 或 w/e 之后。直到阅读就绪通知,有东西被发回给它,我尝试阅读我可以手动调用但它似乎没有任何建议?

我的一小部分代码:

ConnectionManager.cpp

ConnectionManager::ConnectionManager(QObject *parent)
    : QTcpServer(parent)
{
    socket = new QTcpSocket(this);

    connect(socket, SIGNAL(readyRead()), this, SLOT(readyread()));
    connect(socket, SIGNAL(disconnected()), this, SLOT(disconnect()));

    socket -> connectToHost("192.168.0.119",60000);
}


QString ConnectionManager::getMessage()
{
    //sleep(1);
    while (inMessage == "")
    {
        //my attempt at calling read() manually it will read nothing
        QByteArray data = socket->readAll();

        //just checkign what i am getting my server will immediately return a trivial 
        //string i.e "carly, santos, andrew, bob"
        std::cout << data.data() << "+ 8" << std::endl;
        inMessage = data;
    }
    return inMessage;
}

void ConnectionManager::sendMessage(QString &message) 
{
    socket -> write(message.toUtf8());
}

//my socket for reading whenever something is sent?
void ConnectionManager::readyread()
{
    QByteArray data = socket->readAll();
    inMessage = data;
    std::cout << data.data() << "+ 1" << std::endl;
}

好的,现在我的控制器.cpp

void Controller::openTALogin()
{
    //TODO send message to Server
    QString buffer = Fill::fillBufferState("Client", "TA");
    //std::cout << buffer.toUtf8().data() << std::endl;
    myConnection->sendMessage(buffer); // <- this works great =)

    //sleep(7);
    std::cout << "1234" << std::endl;

    QString in = myConnection -> getMessage(); //<- gets nothing -.-

    std::cout << in.toUtf8().data() << "+ 12" << std::endl;
    //TODO recieve List from server
    //ForNow
    QLinkedList<QString> *testList = new QLinkedList<QString>();

    Fill::fillLinkedList(testList, in); 
    //testList -> push_front("jabba:5:hut:1");
    //testList -> push_front("blind:3:mice:2");
    //testList -> push_front("eat:5:day:3");
    //testList -> push_front("hello:4:goodbye:4");


    delete userWindow;
    taLoginWindow = new TALoginWindow(this, testList);
    taLoginWindow -> show();
    testList -> clear();
    delete(testList);

}

此函数执行后在此处收到消息,我记得表单使用 C 样式 TCP/IP 连接读取会等到有数据继续,但这里什么都没有似乎很酷?

【问题讨论】:

  • 您是否在 NextButtonPressed() 方法内部阻塞?如果是这样,请不要这样做。为了让 Qt 的事件循环能够及时运行,Qt/GUI 线程中的所有方法都应该尽快返回。
  • 我的下一个按钮按下方法例如将简单地调用控制器'openNextPage',在这种情况下它将是 OpenTALoginWindow(),我不相信我阻止任何东西,但我相信有 2 是 2控制流会抛出我的程序,用户控制视图的那个让我们称之为页面导航,然后有连接管理,从技术上讲,可以随时从服务器发送信号,这有意义吗?我想我需要暂停函数的执行并允许连接管理来检查更新有没有办法做到这一点?

标签: c++ qt tcp client-server


【解决方案1】:

您发送消息然后立即尝试获取响应,这将不起作用,因为您需要返回事件循环才能写入或读取任何内容

将您的 Controller::openTALogin 方法拆分为 2 个

void Controller::openTALogin()
{
    //TODO send message to Server
    QString buffer = Fill::fillBufferState("Client", "TA");
    //std::cout << buffer.toUtf8().data() << std::endl;
    myConnection->sendMessage(buffer); // <- this works great =)
}

void Controller::gotResponce(QString in)
{

    std::cout << in.toUtf8().data() << "+ 12" << std::endl;
    //TODO recieve List from server
    //ForNow
    QLinkedList<QString> *testList = new QLinkedList<QString>();

    Fill::fillLinkedList(testList, in); 
    //testList -> push_front("jabba:5:hut:1");
    //testList -> push_front("blind:3:mice:2");
    //testList -> push_front("eat:5:day:3");
    //testList -> push_front("hello:4:goodbye:4");


    delete userWindow;
    taLoginWindow = new TALoginWindow(this, testList);
    taLoginWindow -> show();
    testList -> clear();
    delete(testList);

}

并在您的 readyRead 中调用第二部分:

void ConnectionManager::readyread()
{
    QByteArray data = socket->readAll();
    inMessage = data;
    std::cout << data.data() << "+ 1" << std::endl;
    emit recievedMessage(QString(inMessage)); // using signal here
}

【讨论】:

  • 我明白了!这是有道理的,我会让你知道它是怎么回事!谢谢!
  • 我对这里使用信号有点困惑,所以我发出一个信号,它连接到哪里?并且在您得到的响应中,“in”变量未声明是故意的吗?
  • 你将myConnection的recievedMessage信号连接到Controller::gotResponce,in是它的参数
  • 你的回答解决了这个问题,但我有第二个相当相关的问题,也许你可以帮助我?我所有的 ui 页面都包含在控制器类中,我试图找出一种方法,以便特定页面可以从我的连接管理器接收即时更新?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-28
相关资源
最近更新 更多