无法从套接字中正确读取

时间:2012-09-26 09:46:02

标签: c++ qt sockets

我有一个服务器应用程序,它发送一些 xor加密字符串。我正在从我的QT客户端应用程序中读取它们。有时,服务器速度较慢,我无法接收整个字符串。我尝试了类似下面的东西,但它被卡住了(见下面的评论)。我怎么能等到我拥有整个数据。我试过bytesAviable(),但后来我又陷入困境(无限循环)

QTcpSocket * sock = static_cast<QTcpSocket*>(this->sender());
if (key == 0)
{
    QString recv(sock->readLine());
    key = recv.toInt();
    qDebug() << "Cheia este " << key;

    char * response = enc_dec("#AUTH|admin|admin",strlen("#AUTH|admin|admin"),key);
    sock->write(response);
}
else
{
    busy = true;
    while (sock->bytesAvailable() > 0)
    {
        unsigned short word;
        sock->read((char*)(&word),2);
        qDebug()<<word;
        //Sleep(100); if i do this than it works great!
        QByteArray bts = sock->read(word);
        while (bts.length() < word)
        {
            char bit; //here get's stuck
            if (sock->read(&bit,1) > 0)
                bts.append(bit);
            sock->flush();
        }

        char * decodat = enc_dec((char*)bts.data(),bts.length() - 2,key);
        qDebug() << decodat;
    }

}

2 个答案:

答案 0 :(得分:1)

我不知道key == 0的含义是什么,但你几乎肯定会误导available(),就像几乎所有曾经打过它的人一样,包括我。它告诉您可以在不阻塞的情况下读取多少数据。它与最终可以通过连接传递多少数据无关,原因是有些TCP可以告诉你前者,而不是后者。实际上后者没有任何实际意义,考虑到同伴可以从现在开始一直写到世界末日。您应该阻止并循环,直到您已经阅读了下一部分工作所需的数据量。

答案 1 :(得分:0)

我建议你做以下事情:

QObject::connect(this->m_TCPSocket, SIGNAL(readyRead()), this, SLOT(processRecivedDatagrams()));

一些解释:

  1. 创建一个将管理网络的类实例很方便;
  2. 其中一个成员是TCPSocket上的指针;
  3. 在构造函数中实现来自套接字readyRead()的信号连接,当SLOT(processRecivedDatagrams())传递所需数据时,该信号被终止。负责处理recived datagrams /在这种情况下是processRecivedDatagrams(),也实现了这个插槽
  4. 请注意,管理网络的类必须从QObject继承,并在其中继承MOC的s declaration include macros Q_OBject`。

    更新

    我还提供将已回收的数据存储在容器中,如堆栈或队列这将允许您同步发件人和reciver(容器,在这种情况下就像缓冲区一样)< / p>

    // SLOT:
    
    
    void Network::processRecivedDatagrams(void)
    {
        if (!this->m_flagLocked) // use analog of mutex 
        {
            this->m_flagLocked = true; // lock resource
    
        QByteArray datagram;
        do 
        {
            datagram.resize(m_TCPSocket->pendingDatagramSize());
            m_TCPSocket->readDatagram(datagram.data(), datagram.size());
        }
                Qt::String YourString; // actualy I don`t remember how to declare Qt string
        while (m_TCPSocket->hasPendingDatagrams());
        QDataStream in (&datagram, QIODevice::ReadOnly);
    
            in  >> YourString
    
    
    
            --numberOfDatagrams;
        }
    
        this->m_flagLocked = false; // unlock resource
    }
    

    }