QAbstractSocket: discard input data when opened only for writing

A buffered TCP socket might be open only for writing purpose. As a
possible use case of the API, this patch avoids accumulation of
unwanted data in the internal read buffer.

Change-Id: I2759c1e04968d24e2ae71f3eca05e7e560cd8a41
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Alex Trotsenko 2015-09-03 10:12:02 +03:00
parent 353b160a4a
commit 5237b97f26
2 changed files with 33 additions and 1 deletions

View File

@ -1284,7 +1284,7 @@ bool QAbstractSocketPrivate::readFromSocket()
buffer.chop(bytesToRead);
return true;
}
buffer.chop(bytesToRead - (readBytes < 0 ? qint64(0) : readBytes));
buffer.chop(bytesToRead - ((readBytes < 0 || !q->isReadable()) ? qint64(0) : readBytes));
#if defined(QABSTRACTSOCKET_DEBUG)
qDebug("QAbstractSocketPrivate::readFromSocket() got %lld bytes, buffer size = %lld",
readBytes, buffer.size());

View File

@ -201,6 +201,7 @@ private slots:
void setSocketOption();
void clientSendDataOnDelayedDisconnect();
void serverDisconnectWithBuffered();
void socketDiscardDataInWriteMode();
protected slots:
void nonBlockingIMAP_hostFound();
@ -3028,5 +3029,36 @@ void tst_QTcpSocket::serverDisconnectWithBuffered()
delete socket;
}
// Test buffered sockets discard input when opened in WriteOnly mode
void tst_QTcpSocket::socketDiscardDataInWriteMode()
{
QFETCH_GLOBAL(bool, setProxy);
if (setProxy)
return;
QTcpServer tcpServer;
QTcpSocket *socket = newSocket();
QVERIFY(tcpServer.listen(QHostAddress::LocalHost));
socket->connectToHost(tcpServer.serverAddress(), tcpServer.serverPort(),
QIODevice::WriteOnly);
QVERIFY(socket->waitForConnected(5000)); // ready for write
QCOMPARE(socket->state(), QAbstractSocket::ConnectedState);
// Accept connection on server side
QVERIFY2(tcpServer.waitForNewConnection(5000), "Network timeout");
QTcpSocket *newConnection = tcpServer.nextPendingConnection();
// Send one char and drop link
QVERIFY(newConnection != NULL);
QVERIFY(newConnection->putChar(0));
QVERIFY(newConnection->flush());
delete newConnection;
QVERIFY(socket->waitForReadyRead(5000)); // discard input
QVERIFY(socket->atEnd());
delete socket;
}
QTEST_MAIN(tst_QTcpSocket)
#include "tst_qtcpsocket.moc"