Есть сокет. Попытался читать из него QDataStream.
На больших данных operator >> возвращает пустые данные.
Есть предположение, что QDataStream читает пока читается, но если данные приходят кусками, то он не успевает все вычитывать.
Есть ли что стандартное, для чтения потока? То есть читать пока читается либо пока не порвется соединение.
while(socket.isValid())
{
if (socket.waitForReadReady())
{
...
}
}
socket.close();
while(socket.isValid())
{
QDataStream stream(&socket);
stream << QString("...");
if (socket.waitForReadReady())
{
QString data;
stream >> data;
...
}
}
#include <QtCore/QCoreApplication>
#include <QTcpServer>
#include <QTcpSocket>
#include <QCoreApplication>
class Client {
private:
QTcpSocket m_socket;
public :
Client () {}
~Client() {}
void connect (void)
{
m_socket.connectToHost(QHostAddress::LocalHost, 7777);
if (!m_socket.waitForConnected())
{
QT_THROW(m_socket.errorString());
}
qDebug("CONNECTED !!!");
}
void disconnect(void)
{
m_socket.close();
qDebug("DISCONNECTED !!!");
}
bool isValid(void) const { return m_socket.isValid(); }
};
class Server : public QTcpServer {
private:
Client m_client;
virtual void timerEvent ( QTimerEvent * event )
{
static uint counter = 0;
switch (++counter)
{
case 1 : m_client.connect(); break;
case 2 : m_client.disconnect(); break;
}
}
virtual void incomingConnection( int session )
{
QTcpSocket socket(this);
socket.setSocketDescriptor(session);
while (socket.isValid())
{
Q_ASSERT(m_client.isValid()); // Здесь сработает ASSERT, но socket.isValid() :)
qApp->processEvents();
}
socket.close();
}
public :
Server ()
{
if (!listen(QHostAddress::Any, 7777))
{
QT_THROW(QTcpServer::errorString());
}
startTimer(100);
}
virtual ~Server() {}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Server server;
return a.exec();
}
При серилизации QString вначале записывается ее длина, поэтому QDataStream может определить пришла она полностью или нет. Если она пришла не полностью, то ему не остается ничего другого, кроме возвращения пустой строки при чтении.
Можно пробовать читать из потока и если вернулась пустая строка, то ждать прихода следующего пакета и пробовать читать снова.
Можно писать raw-строки без использования QDataStream и в качестве конца строки использовать "\r\n" (как это делается в http, ftp, ...). Тогда каждую порцию строку можно дописывать в буфер и контролировать маркер конца строки, если он получен, то вырезаем ее из буфера и обрабатываем.
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)