Don't brute-force reading the socket
The package will arrive eventually, and dataReceived will be emitted. Otherwise we just end up calling dataReceived to no end. Thanks Matthias Gerstner <mgerstner@suse.de> for reporting this.
This commit is contained in:
parent
024e5f23db
commit
8112729eb0
2 changed files with 29 additions and 10 deletions
|
@ -24,14 +24,6 @@ void SocketLineReader::dataReceived()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//If we still have things to read from the socket, call dataReceived again
|
|
||||||
//We do this manually because we do not trust readyRead to be emitted again
|
|
||||||
//So we call this method again just in case.
|
|
||||||
if (m_socket->bytesAvailable() > 0) {
|
|
||||||
QMetaObject::invokeMethod(this, "dataReceived", Qt::QueuedConnection);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//If we have any packets, tell it to the world.
|
//If we have any packets, tell it to the world.
|
||||||
if (!m_packets.isEmpty()) {
|
if (!m_packets.isEmpty()) {
|
||||||
Q_EMIT readyRead();
|
Q_EMIT readyRead();
|
||||||
|
|
|
@ -13,16 +13,19 @@
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QEventLoop>
|
#include <QEventLoop>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QSignalSpy>
|
||||||
|
|
||||||
class TestSocketLineReader : public QObject
|
class TestSocketLineReader : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void initTestCase();
|
void init();
|
||||||
|
void cleanup() { delete m_server; }
|
||||||
void newPacket();
|
void newPacket();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void socketLineReader();
|
void socketLineReader();
|
||||||
|
void badData();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTimer m_timer;
|
QTimer m_timer;
|
||||||
|
@ -33,8 +36,9 @@ private:
|
||||||
SocketLineReader* m_reader;
|
SocketLineReader* m_reader;
|
||||||
};
|
};
|
||||||
|
|
||||||
void TestSocketLineReader::initTestCase()
|
void TestSocketLineReader::init()
|
||||||
{
|
{
|
||||||
|
m_packets.clear();
|
||||||
m_server = new Server(this);
|
m_server = new Server(this);
|
||||||
|
|
||||||
QVERIFY2(m_server->listen(QHostAddress::LocalHost, 8694), "Failed to create local tcp server");
|
QVERIFY2(m_server->listen(QHostAddress::LocalHost, 8694), "Failed to create local tcp server");
|
||||||
|
@ -85,6 +89,29 @@ void TestSocketLineReader::socketLineReader()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestSocketLineReader::badData()
|
||||||
|
{
|
||||||
|
const QList<QByteArray> dataToSend = { "data1\n", "data" }; //does not end in a \n
|
||||||
|
for (const QByteArray& line : qAsConst(dataToSend)) {
|
||||||
|
m_conn->write(line);
|
||||||
|
}
|
||||||
|
m_conn->flush();
|
||||||
|
|
||||||
|
QSignalSpy spy(m_server, &QTcpServer::newConnection);
|
||||||
|
QVERIFY(m_server->hasPendingConnections() || spy.wait(1000));
|
||||||
|
QSslSocket* sock = m_server->nextPendingConnection();
|
||||||
|
|
||||||
|
QVERIFY2(sock != nullptr, "Could not open a connection to the client");
|
||||||
|
|
||||||
|
m_reader = new SocketLineReader(sock, this);
|
||||||
|
connect(m_reader, &SocketLineReader::readyRead, this, &TestSocketLineReader::newPacket);
|
||||||
|
m_timer.start();
|
||||||
|
m_loop.exec();
|
||||||
|
|
||||||
|
QCOMPARE(m_packets.count(), 1);
|
||||||
|
QCOMPARE(m_packets[0], dataToSend[0]);
|
||||||
|
}
|
||||||
|
|
||||||
void TestSocketLineReader::newPacket()
|
void TestSocketLineReader::newPacket()
|
||||||
{
|
{
|
||||||
int maxLoops = 5;
|
int maxLoops = 5;
|
||||||
|
|
Loading…
Reference in a new issue