qt 6.5.1 original

This commit is contained in:
kleuter
2023-10-29 23:33:08 +01:00
parent 71d22ab6b0
commit 85d238dfda
21202 changed files with 5499099 additions and 0 deletions

View File

@ -0,0 +1,20 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
if(QT_FEATURE_private_tests)
add_subdirectory(qhttpsocketengine)
add_subdirectory(qtcpsocket)
add_subdirectory(qsocks5socketengine)
add_subdirectory(platformsocketengine)
endif()
add_subdirectory(qudpsocket)
add_subdirectory(qabstractsocket)
if(NOT ANDROID)
# QTBUG-87387
add_subdirectory(qlocalsocket)
# QTBUG-87388
add_subdirectory(qtcpserver)
endif()
if(QT_FEATURE_sctp)
add_subdirectory(qsctpsocket)
endif()

View File

@ -0,0 +1,11 @@
[tcpLoopbackPerformance]
windows-10 msvc-2015
windows-7sp1
[receiveUrgentData]
windows-10 msvc-2015
windows-7sp1
[serverTest]
windows-10 msvc-2015
windows-7sp1
[tcpLoopbackPerformance]
windows

View File

@ -0,0 +1,27 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
if(NOT QT_FEATURE_private_tests)
return()
endif()
#####################################################################
## tst_platformsocketengine Test:
#####################################################################
qt_internal_add_test(tst_platformsocketengine
SOURCES
tst_platformsocketengine.cpp
LIBRARIES
Qt::CorePrivate
Qt::NetworkPrivate
QT_TEST_SERVER_LIST "cyrus"
)
## Scopes:
#####################################################################
qt_internal_extend_target(tst_platformsocketengine CONDITION WIN32
LIBRARIES
ws2_32
)

View File

@ -0,0 +1,655 @@
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtTest/QTest>
#include <qcoreapplication.h>
#include <qdatastream.h>
#include <qhostaddress.h>
#include <qelapsedtimer.h>
#ifdef Q_OS_UNIX
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#endif
#ifdef Q_OS_VXWORKS
#include <sockLib.h>
#endif
#include <stddef.h>
#define PLATFORMSOCKETENGINE QNativeSocketEngine
#define PLATFORMSOCKETENGINESTRING "QNativeSocketEngine"
#include <private/qnativesocketengine_p_p.h>
#include <qstringlist.h>
#include "../../../network-settings.h"
class tst_PlatformSocketEngine : public QObject
{
Q_OBJECT
private slots:
void initTestCase();
void construction();
void simpleConnectToIMAP();
void udpLoopbackTest();
void udpIPv6LoopbackTest();
void broadcastTest();
void serverTest();
void udpLoopbackPerformance();
void tcpLoopbackPerformance();
#if 0
void readWriteBufferSize();
#endif
void bind();
void networkError();
void setSocketDescriptor();
void invalidSend();
void receiveUrgentData();
void tooManySockets();
};
void tst_PlatformSocketEngine::initTestCase()
{
#ifdef QT_TEST_SERVER
QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::imapServerName(), 143));
#else
if (!QtNetworkSettings::verifyTestNetworkSettings())
QSKIP("No network test server available");
#endif
}
//---------------------------------------------------------------------------
void tst_PlatformSocketEngine::construction()
{
PLATFORMSOCKETENGINE socketDevice;
QVERIFY(!socketDevice.isValid());
// Initialize device
QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
QVERIFY(socketDevice.isValid());
QCOMPARE(socketDevice.protocol(), QAbstractSocket::IPv4Protocol);
QCOMPARE(socketDevice.socketType(), QAbstractSocket::TcpSocket);
QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState);
QVERIFY(socketDevice.socketDescriptor() != -1);
QCOMPARE(socketDevice.localAddress(), QHostAddress());
QCOMPARE(socketDevice.localPort(), quint16(0));
QCOMPARE(socketDevice.peerAddress(), QHostAddress());
QCOMPARE(socketDevice.peerPort(), quint16(0));
QCOMPARE(socketDevice.error(), QAbstractSocket::UnknownSocketError);
QCOMPARE(socketDevice.option(QNativeSocketEngine::NonBlockingSocketOption), -1);
QTest::ignoreMessage(QtWarningMsg, PLATFORMSOCKETENGINESTRING "::bytesAvailable() was called in QAbstractSocket::UnconnectedState");
QCOMPARE(socketDevice.bytesAvailable(), -1);
QTest::ignoreMessage(QtWarningMsg, PLATFORMSOCKETENGINESTRING "::hasPendingDatagrams() was called in QAbstractSocket::UnconnectedState");
QVERIFY(!socketDevice.hasPendingDatagrams());
}
//---------------------------------------------------------------------------
void tst_PlatformSocketEngine::simpleConnectToIMAP()
{
PLATFORMSOCKETENGINE socketDevice;
// Initialize device
QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState);
const bool isConnected = socketDevice.connectToHost(QtNetworkSettings::imapServerIp(), 143);
if (!isConnected) {
QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState);
QVERIFY(socketDevice.waitForWrite());
QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectedState);
}
QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectedState);
QCOMPARE(socketDevice.peerAddress(), QtNetworkSettings::imapServerIp());
// Wait for the greeting
QVERIFY(socketDevice.waitForRead());
// Read the greeting
qint64 available = socketDevice.bytesAvailable();
QVERIFY(available > 0);
QByteArray array;
array.resize(available);
QVERIFY(socketDevice.read(array.data(), array.size()) == available);
// Check that the greeting is what we expect it to be
QVERIFY2(QtNetworkSettings::compareReplyIMAP(array), array.constData());
// Write a logout message
QByteArray array2 = "ZZZ LOGOUT\r\n";
QVERIFY(socketDevice.write(array2.data(),
array2.size()) == array2.size());
// Wait for the response
QVERIFY(socketDevice.waitForRead());
available = socketDevice.bytesAvailable();
QVERIFY(available > 0);
array.resize(available);
QVERIFY(socketDevice.read(array.data(), array.size()) == available);
// Check that the greeting is what we expect it to be
QCOMPARE(array.constData(),
"* BYE LOGOUT received\r\n"
"ZZZ OK Completed\r\n");
// Wait for the response
QVERIFY(socketDevice.waitForRead());
char c;
QVERIFY(socketDevice.read(&c, sizeof(c)) == -1);
QCOMPARE(socketDevice.error(), QAbstractSocket::RemoteHostClosedError);
QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState);
}
//---------------------------------------------------------------------------
void tst_PlatformSocketEngine::udpLoopbackTest()
{
PLATFORMSOCKETENGINE udpSocket;
// Initialize device #1
QVERIFY(udpSocket.initialize(QAbstractSocket::UdpSocket));
QVERIFY(udpSocket.isValid());
QVERIFY(udpSocket.socketDescriptor() != -1);
QCOMPARE(udpSocket.protocol(), QAbstractSocket::IPv4Protocol);
QCOMPARE(udpSocket.socketType(), QAbstractSocket::UdpSocket);
QCOMPARE(udpSocket.state(), QAbstractSocket::UnconnectedState);
// Bind #1 to localhost
QVERIFY(udpSocket.bind(QHostAddress("127.0.0.1"), 0));
QCOMPARE(udpSocket.state(), QAbstractSocket::BoundState);
quint16 port = udpSocket.localPort();
QVERIFY(port != 0);
// Initialize device #2
PLATFORMSOCKETENGINE udpSocket2;
QVERIFY(udpSocket2.initialize(QAbstractSocket::UdpSocket));
// Connect device #2 to #1
QVERIFY(udpSocket2.connectToHost(QHostAddress("127.0.0.1"), port));
QCOMPARE(udpSocket2.state(), QAbstractSocket::ConnectedState);
// Write a message to #1
QByteArray message1 = "hei der";
QVERIFY(udpSocket2.write(message1.data(),
message1.size()) == message1.size());
// Read the message from #2
QVERIFY(udpSocket.waitForRead());
QVERIFY(udpSocket.hasPendingDatagrams());
qint64 available = udpSocket.pendingDatagramSize();
QVERIFY(available > 0);
QByteArray answer;
answer.resize(available);
QIpPacketHeader header;
QCOMPARE(udpSocket.readDatagram(answer.data(), answer.size(),
&header, QAbstractSocketEngine::WantDatagramSender),
qint64(message1.size()));
QVERIFY(header.senderAddress == QHostAddress("127.0.0.1"));
QCOMPARE(header.senderAddress, QHostAddress("127.0.0.1"));
QVERIFY(header.senderPort != 0);
}
//---------------------------------------------------------------------------
void tst_PlatformSocketEngine::udpIPv6LoopbackTest()
{
PLATFORMSOCKETENGINE udpSocket;
// Initialize device #1
bool init = udpSocket.initialize(QAbstractSocket::UdpSocket, QAbstractSocket::IPv6Protocol);
if (!init) {
QCOMPARE(udpSocket.error(), QAbstractSocket::UnsupportedSocketOperationError);
} else {
QCOMPARE(udpSocket.protocol(), QAbstractSocket::IPv6Protocol);
// Bind #1 to localhost
QVERIFY(udpSocket.bind(QHostAddress("::1"), 0));
QCOMPARE(udpSocket.state(), QAbstractSocket::BoundState);
quint16 port = udpSocket.localPort();
QVERIFY(port != 0);
// Initialize device #2
PLATFORMSOCKETENGINE udpSocket2;
QVERIFY(udpSocket2.initialize(QAbstractSocket::UdpSocket, QAbstractSocket::IPv6Protocol));
// Connect device #2 to #1
QVERIFY(udpSocket2.connectToHost(QHostAddress("::1"), port));
QCOMPARE(udpSocket2.state(), QAbstractSocket::ConnectedState);
// Write a message to #1
QByteArray message1 = "hei der";
QVERIFY(udpSocket2.write(message1.data(),
message1.size()) == message1.size());
// Read the message from #2
QVERIFY(udpSocket.waitForRead());
QVERIFY(udpSocket.hasPendingDatagrams());
qint64 available = udpSocket.pendingDatagramSize();
QVERIFY(available > 0);
QByteArray answer;
answer.resize(available);
QIpPacketHeader header;
QCOMPARE(udpSocket.readDatagram(answer.data(), answer.size(),
&header, QAbstractSocketEngine::WantDatagramSender),
qint64(message1.size()));
QVERIFY(header.senderAddress == QHostAddress("::1"));
QCOMPARE(header.senderAddress, QHostAddress("::1"));
QVERIFY(header.senderPort != 0);
}
}
//---------------------------------------------------------------------------
void tst_PlatformSocketEngine::broadcastTest()
{
#ifdef Q_OS_AIX
QSKIP("Broadcast does not work on darko");
#endif
PLATFORMSOCKETENGINE broadcastSocket;
// Initialize a regular Udp socket
QVERIFY(broadcastSocket.initialize(QAbstractSocket::UdpSocket, QAbstractSocket::AnyIPProtocol));
// Bind to any port on all interfaces
QVERIFY(broadcastSocket.bind(QHostAddress::Any, 0));
QCOMPARE(broadcastSocket.state(), QAbstractSocket::BoundState);
quint16 port = broadcastSocket.localPort();
QVERIFY(port > 0);
// Broadcast an inappropriate troll message
QByteArray trollMessage
= "MOOT wtf is a MOOT? talk english not your sutpiD ENGLISH.";
qint64 written = broadcastSocket.writeDatagram(trollMessage.data(),
trollMessage.size(),
QIpPacketHeader(QHostAddress::Broadcast, port));
QVERIFY2(written != -1, qt_error_string().toLocal8Bit());
QCOMPARE((int)written, trollMessage.size());
// Wait until we receive it ourselves
#if defined(Q_OS_FREEBSD)
QEXPECT_FAIL("", "Broadcasting to 255.255.255.255 does not work on FreeBSD", Abort);
#endif
QVERIFY(broadcastSocket.waitForRead());
QVERIFY(broadcastSocket.hasPendingDatagrams());
qlonglong available = broadcastSocket.pendingDatagramSize();
QByteArray response;
response.resize(available);
QVERIFY(broadcastSocket.readDatagram(response.data(), response.size())
== response.size());
QCOMPARE(response, trollMessage);
}
//---------------------------------------------------------------------------
void tst_PlatformSocketEngine::serverTest()
{
PLATFORMSOCKETENGINE server;
// Initialize a Tcp socket
QVERIFY(server.initialize(QAbstractSocket::TcpSocket));
// Bind to any port on all interfaces
QVERIFY(server.bind(QHostAddress("0.0.0.0"), 0));
QCOMPARE(server.state(), QAbstractSocket::BoundState);
quint16 port = server.localPort();
// Listen for incoming connections
QVERIFY(server.listen(50));
QCOMPARE(server.state(), QAbstractSocket::ListeningState);
// Initialize a Tcp socket
PLATFORMSOCKETENGINE client;
QVERIFY(client.initialize(QAbstractSocket::TcpSocket));
if (!client.connectToHost(QHostAddress("127.0.0.1"), port)) {
QCOMPARE(client.state(), QAbstractSocket::ConnectingState);
QVERIFY(client.waitForWrite());
QCOMPARE(client.state(), QAbstractSocket::ConnectedState);
}
// The server accepts the connection
int socketDescriptor = server.accept();
QVERIFY(socketDescriptor > 0);
// A socket device is initialized on the server side, passing the
// socket descriptor from accept(). It's pre-connected.
PLATFORMSOCKETENGINE serverSocket;
QVERIFY(serverSocket.initialize(socketDescriptor));
QCOMPARE(serverSocket.state(), QAbstractSocket::ConnectedState);
// The server socket sends a greeting to the clietn
QByteArray greeting = "Greetings!";
QVERIFY(serverSocket.write(greeting.data(),
greeting.size()) == greeting.size());
// The client waits for the greeting to arrive
QVERIFY(client.waitForRead());
qint64 available = client.bytesAvailable();
QVERIFY(available > 0);
// The client reads the greeting and checks that it's correct
QByteArray response;
response.resize(available);
QVERIFY(client.read(response.data(),
response.size()) == response.size());
QCOMPARE(response, greeting);
}
//---------------------------------------------------------------------------
void tst_PlatformSocketEngine::udpLoopbackPerformance()
{
PLATFORMSOCKETENGINE udpSocket;
// Initialize device #1
QVERIFY(udpSocket.initialize(QAbstractSocket::UdpSocket));
QVERIFY(udpSocket.isValid());
QVERIFY(udpSocket.socketDescriptor() != -1);
QCOMPARE(udpSocket.protocol(), QAbstractSocket::IPv4Protocol);
QCOMPARE(udpSocket.socketType(), QAbstractSocket::UdpSocket);
QCOMPARE(udpSocket.state(), QAbstractSocket::UnconnectedState);
// Bind #1 to localhost
QVERIFY(udpSocket.bind(QHostAddress("127.0.0.1"), 0));
QCOMPARE(udpSocket.state(), QAbstractSocket::BoundState);
quint16 port = udpSocket.localPort();
QVERIFY(port != 0);
// Initialize device #2
PLATFORMSOCKETENGINE udpSocket2;
QVERIFY(udpSocket2.initialize(QAbstractSocket::UdpSocket));
// Connect device #2 to #1
QVERIFY(udpSocket2.connectToHost(QHostAddress("127.0.0.1"), port));
QCOMPARE(udpSocket2.state(), QAbstractSocket::ConnectedState);
const int messageSize = 8192;
QByteArray message1(messageSize, '@');
QByteArray answer(messageSize, '@');
QHostAddress localhost = QHostAddress::LocalHost;
qlonglong readBytes = 0;
QElapsedTimer timer;
timer.start();
while (timer.elapsed() < 5000) {
udpSocket2.write(message1.data(), message1.size());
udpSocket.waitForRead();
while (udpSocket.hasPendingDatagrams()) {
readBytes += (qlonglong) udpSocket.readDatagram(answer.data(),
answer.size());
}
}
qDebug("\t\t%.1fMB/%.1fs: %.1fMB/s",
readBytes / (1024.0 * 1024.0),
timer.elapsed() / 1024.0,
(readBytes / (timer.elapsed() / 1000.0)) / (1024 * 1024));
}
//---------------------------------------------------------------------------
void tst_PlatformSocketEngine::tcpLoopbackPerformance()
{
PLATFORMSOCKETENGINE server;
// Initialize a Tcp socket
QVERIFY(server.initialize(QAbstractSocket::TcpSocket));
// Bind to any port on all interfaces
QVERIFY(server.bind(QHostAddress("0.0.0.0"), 0));
QCOMPARE(server.state(), QAbstractSocket::BoundState);
quint16 port = server.localPort();
// Listen for incoming connections
QVERIFY(server.listen(50));
QCOMPARE(server.state(), QAbstractSocket::ListeningState);
// Initialize a Tcp socket
PLATFORMSOCKETENGINE client;
QVERIFY(client.initialize(QAbstractSocket::TcpSocket));
// Connect to our server
if (!client.connectToHost(QHostAddress("127.0.0.1"), port)) {
QCOMPARE(client.state(), QAbstractSocket::ConnectingState);
QVERIFY(client.waitForWrite());
QCOMPARE(client.state(), QAbstractSocket::ConnectedState);
}
// The server accepts the connection
int socketDescriptor = server.accept();
QVERIFY(socketDescriptor > 0);
// A socket device is initialized on the server side, passing the
// socket descriptor from accept(). It's pre-connected.
PLATFORMSOCKETENGINE serverSocket;
QVERIFY(serverSocket.initialize(socketDescriptor));
QCOMPARE(serverSocket.state(), QAbstractSocket::ConnectedState);
const int messageSize = 1024 * 256;
QByteArray message1(messageSize, '@');
QByteArray answer(messageSize, '@');
QElapsedTimer timer;
timer.start();
qlonglong readBytes = 0;
while (timer.elapsed() < 5000) {
qlonglong written = serverSocket.write(message1.data(), message1.size());
while (written > 0) {
client.waitForRead();
if (client.bytesAvailable() > 0) {
qlonglong readNow = client.read(answer.data(), answer.size());
written -= readNow;
readBytes += readNow;
}
}
}
qDebug("\t\t%.1fMB/%.1fs: %.1fMB/s",
readBytes / (1024.0 * 1024.0),
timer.elapsed() / 1024.0,
(readBytes / (timer.elapsed() / 1000.0)) / (1024 * 1024));
}
#if 0 // unused
//---------------------------------------------------------------------------
void tst_PlatformSocketEngine::readWriteBufferSize()
{
PLATFORMSOCKETENGINE device;
QVERIFY(device.initialize(QAbstractSocket::TcpSocket));
qint64 bufferSize = device.receiveBufferSize();
QVERIFY(bufferSize != -1);
device.setReceiveBufferSize(bufferSize + 1);
QVERIFY(device.receiveBufferSize() > bufferSize);
bufferSize = device.sendBufferSize();
QVERIFY(bufferSize != -1);
device.setSendBufferSize(bufferSize + 1);
QVERIFY(device.sendBufferSize() > bufferSize);
}
#endif
//---------------------------------------------------------------------------
void tst_PlatformSocketEngine::tooManySockets()
{
#if defined Q_OS_WIN
QSKIP("Certain windows machines suffocate and spend too much time in this test.");
#endif
QList<PLATFORMSOCKETENGINE *> sockets;
PLATFORMSOCKETENGINE *socketLayer = 0;
for (;;) {
socketLayer = new PLATFORMSOCKETENGINE;
sockets.append(socketLayer);
if (!socketLayer->initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol))
break;
}
QCOMPARE(socketLayer->error(), QAbstractSocket::SocketResourceError);
qDeleteAll(sockets);
}
//---------------------------------------------------------------------------
void tst_PlatformSocketEngine::bind()
{
PLATFORMSOCKETENGINE binder;
QVERIFY(binder.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
QCOMPARE(binder.bind(QHostAddress::AnyIPv4, 82), QtNetworkSettings::canBindToLowPorts());
if (!QtNetworkSettings::canBindToLowPorts())
QCOMPARE(binder.error(), QAbstractSocket::SocketAccessError);
PLATFORMSOCKETENGINE binder2;
QVERIFY(binder2.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
QVERIFY(binder2.bind(QHostAddress::AnyIPv4, 31180));
PLATFORMSOCKETENGINE binder3;
QVERIFY(binder3.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
QVERIFY(!binder3.bind(QHostAddress::AnyIPv4, 31180));
QCOMPARE(binder3.error(), QAbstractSocket::AddressInUseError);
if (QtNetworkSettings::hasIPv6()) {
PLATFORMSOCKETENGINE binder;
QVERIFY(binder.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv6Protocol));
QCOMPARE(binder.bind(QHostAddress::AnyIPv6, 82), QtNetworkSettings::canBindToLowPorts());
if (!QtNetworkSettings::canBindToLowPorts())
QCOMPARE(binder.error(), QAbstractSocket::SocketAccessError);
PLATFORMSOCKETENGINE binder4;
QVERIFY(binder4.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv6Protocol));
QVERIFY(binder4.bind(QHostAddress::AnyIPv6, 31180));
PLATFORMSOCKETENGINE binder5;
QVERIFY(binder5.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv6Protocol));
QVERIFY(!binder5.bind(QHostAddress::AnyIPv6, 31180));
QCOMPARE(binder5.error(), QAbstractSocket::AddressInUseError);
}
PLATFORMSOCKETENGINE binder6;
QVERIFY(binder6.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::AnyIPProtocol));
QVERIFY(binder6.bind(QHostAddress::Any, 31181));
}
//---------------------------------------------------------------------------
void tst_PlatformSocketEngine::networkError()
{
PLATFORMSOCKETENGINE client;
QVERIFY(client.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
const bool isConnected = client.connectToHost(QtNetworkSettings::imapServerIp(), 143);
if (!isConnected) {
QCOMPARE(client.state(), QAbstractSocket::ConnectingState);
QVERIFY(client.waitForWrite());
QCOMPARE(client.state(), QAbstractSocket::ConnectedState);
}
QCOMPARE(client.state(), QAbstractSocket::ConnectedState);
// An unexpected network error!
#if defined(Q_OS_WIN)
// could use shutdown to produce different errors
::closesocket(client.socketDescriptor());
#else
::close(client.socketDescriptor());
#endif
QVERIFY(client.read(0, 0) == -1);
}
//---------------------------------------------------------------------------
void tst_PlatformSocketEngine::setSocketDescriptor()
{
PLATFORMSOCKETENGINE socket1;
QVERIFY(socket1.initialize(QAbstractSocket::TcpSocket));
PLATFORMSOCKETENGINE socket2;
QVERIFY(socket2.initialize(socket1.socketDescriptor()));
}
//---------------------------------------------------------------------------
void tst_PlatformSocketEngine::invalidSend()
{
PLATFORMSOCKETENGINE socket;
QVERIFY(socket.initialize(QAbstractSocket::TcpSocket));
QTest::ignoreMessage(QtWarningMsg, PLATFORMSOCKETENGINESTRING "::writeDatagram() was called"
" not in QAbstractSocket::BoundState or QAbstractSocket::ConnectedState");
QCOMPARE(socket.writeDatagram("hei", 3, QIpPacketHeader(QHostAddress::LocalHost, 143)),
(qlonglong) -1);
}
//---------------------------------------------------------------------------
void tst_PlatformSocketEngine::receiveUrgentData()
{
PLATFORMSOCKETENGINE server;
QVERIFY(server.initialize(QAbstractSocket::TcpSocket));
// Bind to any port on all interfaces
QVERIFY(server.bind(QHostAddress("0.0.0.0"), 0));
QCOMPARE(server.state(), QAbstractSocket::BoundState);
quint16 port = server.localPort();
QVERIFY(server.listen(50));
QCOMPARE(server.state(), QAbstractSocket::ListeningState);
PLATFORMSOCKETENGINE client;
QVERIFY(client.initialize(QAbstractSocket::TcpSocket));
if (!client.connectToHost(QHostAddress("127.0.0.1"), port)) {
QCOMPARE(client.state(), QAbstractSocket::ConnectingState);
QVERIFY(client.waitForWrite());
QCOMPARE(client.state(), QAbstractSocket::ConnectedState);
}
int socketDescriptor = server.accept();
QVERIFY(socketDescriptor > 0);
PLATFORMSOCKETENGINE serverSocket;
QVERIFY(serverSocket.initialize(socketDescriptor));
QCOMPARE(serverSocket.state(), QAbstractSocket::ConnectedState);
char msg;
int available;
QByteArray response;
// Native OOB data test doesn't work on HP-UX or WinCE
#if !defined(Q_OS_HPUX)
// The server sends an urgent message
msg = 'Q';
QCOMPARE(int(::send(socketDescriptor, &msg, sizeof(msg), MSG_OOB)), 1);
// The client receives the urgent message
QVERIFY(client.waitForRead());
available = client.bytesAvailable();
QCOMPARE(available, 1);
response.resize(available);
QCOMPARE(client.read(response.data(), response.size()), qint64(1));
QCOMPARE(response.at(0), msg);
// The client sends an urgent message
msg = 'T';
int clientDescriptor = client.socketDescriptor();
QCOMPARE(int(::send(clientDescriptor, &msg, sizeof(msg), MSG_OOB)), 1);
// The server receives the urgent message
QVERIFY(serverSocket.waitForRead());
available = serverSocket.bytesAvailable();
QCOMPARE(available, 1);
response.resize(available);
QCOMPARE(serverSocket.read(response.data(), response.size()), qint64(1));
QCOMPARE(response.at(0), msg);
#endif
}
QTEST_MAIN(tst_PlatformSocketEngine)
#include "tst_platformsocketengine.moc"

View File

@ -0,0 +1,13 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qabstractsocket Test:
#####################################################################
qt_internal_add_test(tst_qabstractsocket
SOURCES
tst_qabstractsocket.cpp
LIBRARIES
Qt::Network
)

View File

@ -0,0 +1,68 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QTest>
#include <qcoreapplication.h>
#include <qdebug.h>
#include <qabstractsocket.h>
class tst_QAbstractSocket : public QObject
{
Q_OBJECT
public:
tst_QAbstractSocket();
virtual ~tst_QAbstractSocket();
private slots:
void getSetCheck();
};
tst_QAbstractSocket::tst_QAbstractSocket()
{
}
tst_QAbstractSocket::~tst_QAbstractSocket()
{
}
class MyAbstractSocket : public QAbstractSocket
{
public:
MyAbstractSocket() : QAbstractSocket(QAbstractSocket::TcpSocket, 0) {}
void setLocalPort(quint16 port) { QAbstractSocket::setLocalPort(port); }
void setPeerPort(quint16 port) { QAbstractSocket::setPeerPort(port); }
};
// Testing get/set functions
void tst_QAbstractSocket::getSetCheck()
{
MyAbstractSocket obj1;
// qint64 QAbstractSocket::readBufferSize()
// void QAbstractSocket::setReadBufferSize(qint64)
obj1.setReadBufferSize(qint64(0));
QCOMPARE(qint64(0), obj1.readBufferSize());
obj1.setReadBufferSize((Q_INT64_C(-9223372036854775807) - 1));
QCOMPARE((Q_INT64_C(-9223372036854775807) - 1), obj1.readBufferSize());
obj1.setReadBufferSize(Q_INT64_C(9223372036854775807));
QCOMPARE(Q_INT64_C(9223372036854775807), obj1.readBufferSize());
// quint16 QAbstractSocket::localPort()
// void QAbstractSocket::setLocalPort(quint16)
obj1.setLocalPort(quint16(0));
QCOMPARE(quint16(0), obj1.localPort());
obj1.setLocalPort(quint16(0xffff));
QCOMPARE(quint16(0xffff), obj1.localPort());
// quint16 QAbstractSocket::peerPort()
// void QAbstractSocket::setPeerPort(quint16)
obj1.setPeerPort(quint16(0));
QCOMPARE(quint16(0), obj1.peerPort());
obj1.setPeerPort(quint16(0xffff));
QCOMPARE(quint16(0xffff), obj1.peerPort());
}
QTEST_MAIN(tst_QAbstractSocket)
#include "tst_qabstractsocket.moc"

View File

@ -0,0 +1,5 @@
[downloadBigFile]
windows-10 msvc-2015
windows-7sp1
[ensureEofTriggersNotification]
windows

View File

@ -0,0 +1,29 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
if(NOT QT_FEATURE_private_tests)
return()
endif()
#####################################################################
## tst_qhttpsocketengine Test:
#####################################################################
qt_internal_add_test(tst_qhttpsocketengine
SOURCES
tst_qhttpsocketengine.cpp
LIBRARIES
Qt::CorePrivate
Qt::NetworkPrivate
QT_TEST_SERVER_LIST "squid" "danted" "cyrus" "apache2"
)
## Scopes:
#####################################################################
# QT_TEST_SERVER_LIST = "squid" "danted" "cyrus" "apache2"
qt_internal_extend_target(tst_qhttpsocketengine CONDITION WIN32
LIBRARIES
ws2_32
)

View File

@ -0,0 +1,745 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtTest/QTest>
#include <QtTest/QTestEventLoop>
#include <QtCore/QQueue>
#include <QtCore/QString>
#include <QtCore/QCoreApplication>
#include <private/qhttpsocketengine_p.h>
#include <qhostinfo.h>
#include <qhostaddress.h>
#include <qtcpsocket.h>
#include <qdebug.h>
#include <qelapsedtimer.h>
#include <qtcpserver.h>
#include "../../../network-settings.h"
class tst_QHttpSocketEngine : public QObject
{
Q_OBJECT
private slots:
void initTestCase();
void init();
void construction();
void errorTest_data();
void errorTest();
void simpleConnectToIMAP();
void simpleErrorsAndStates();
void tcpSocketBlockingTest();
void tcpSocketNonBlockingTest();
void downloadBigFile();
// void tcpLoopbackPerformance();
void passwordAuth();
void ensureEofTriggersNotification();
protected slots:
void tcpSocketNonBlocking_hostFound();
void tcpSocketNonBlocking_connected();
void tcpSocketNonBlocking_closed();
void tcpSocketNonBlocking_readyRead();
void tcpSocketNonBlocking_bytesWritten(qint64);
void exitLoopSlot();
void downloadBigFileSlot();
private:
QTcpSocket *tcpSocketNonBlocking_socket;
QStringList tcpSocketNonBlocking_data;
qint64 tcpSocketNonBlocking_totalWritten;
QTcpSocket *tmpSocket;
qint64 bytesAvailable;
};
class MiniHttpServer: public QTcpServer
{
Q_OBJECT
QTcpSocket *client;
QList<QByteArray> dataToTransmit;
public:
QByteArray receivedData;
MiniHttpServer(const QList<QByteArray> &data) : client(0), dataToTransmit(data)
{
listen();
connect(this, SIGNAL(newConnection()), this, SLOT(doAccept()));
}
public slots:
void doAccept()
{
client = nextPendingConnection();
connect(client, SIGNAL(readyRead()), this, SLOT(sendData()));
}
void sendData()
{
receivedData += client->readAll();
int idx = client->property("dataTransmitionIdx").toInt();
if (receivedData.contains("\r\n\r\n") ||
receivedData.contains("\n\n")) {
if (idx < dataToTransmit.size())
client->write(dataToTransmit.at(idx++));
if (idx == dataToTransmit.size()) {
client->disconnectFromHost();
disconnect(client, 0, this, 0);
client = 0;
} else {
client->setProperty("dataTransmitionIdx", idx);
}
}
}
};
void tst_QHttpSocketEngine::initTestCase()
{
#ifdef QT_TEST_SERVER
QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpProxyServerName(), 3128));
QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::socksProxyServerName(), 1080));
QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpServerName(), 80));
QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::imapServerName(), 143));
#else
if (!QtNetworkSettings::verifyTestNetworkSettings())
QSKIP("No network test server available");
#endif
}
void tst_QHttpSocketEngine::init()
{
tmpSocket = 0;
bytesAvailable = 0;
}
//---------------------------------------------------------------------------
void tst_QHttpSocketEngine::construction()
{
QHttpSocketEngine socketDevice;
QVERIFY(!socketDevice.isValid());
// Initialize device
QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
QVERIFY(socketDevice.isValid());
QCOMPARE(socketDevice.protocol(), QAbstractSocket::IPv4Protocol);
QCOMPARE(socketDevice.socketType(), QAbstractSocket::TcpSocket);
QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState);
// QVERIFY(socketDevice.socketDescriptor() != -1);
QCOMPARE(socketDevice.localAddress(), QHostAddress());
QCOMPARE(socketDevice.localPort(), quint16(0));
QCOMPARE(socketDevice.peerAddress(), QHostAddress());
QCOMPARE(socketDevice.peerPort(), quint16(0));
QCOMPARE(socketDevice.error(), QAbstractSocket::UnknownSocketError);
//QTest::ignoreMessage(QtWarningMsg, "QSocketLayer::bytesAvailable() was called in QAbstractSocket::UnconnectedState");
QCOMPARE(socketDevice.bytesAvailable(), 0);
//QTest::ignoreMessage(QtWarningMsg, "QSocketLayer::hasPendingDatagrams() was called in QAbstractSocket::UnconnectedState");
QVERIFY(!socketDevice.hasPendingDatagrams());
}
//---------------------------------------------------------------------------
void tst_QHttpSocketEngine::errorTest_data()
{
QTest::addColumn<QString>("hostname");
QTest::addColumn<int>("port");
QTest::addColumn<QString>("username");
QTest::addColumn<QString>("response");
QTest::addColumn<int>("expectedError");
QQueue<QByteArray> responses;
QTest::newRow("proxy-host-not-found") << "this-host-does-not-exist." << 1080 << QString()
<< QString()
<< int(QAbstractSocket::ProxyNotFoundError);
QTest::newRow("proxy-connection-refused") << QtNetworkSettings::socksProxyServerName() << 2 << QString()
<< QString()
<< int(QAbstractSocket::ProxyConnectionRefusedError);
QTest::newRow("garbage1") << QString() << 0 << QString()
<< "This is not HTTP\r\n\r\n"
<< int(QAbstractSocket::ProxyProtocolError);
QTest::newRow("garbage2") << QString() << 0 << QString()
<< "This is not HTTP"
<< int(QAbstractSocket::ProxyProtocolError);
QTest::newRow("garbage3") << QString() << 0 << QString()
<< ""
<< int(QAbstractSocket::ProxyConnectionClosedError);
QTest::newRow("forbidden") << QString() << 0 << QString()
<< "HTTP/1.0 403 Forbidden\r\n\r\n"
<< int(QAbstractSocket::SocketAccessError);
QTest::newRow("method-not-allowed") << QString() << 0 << QString()
<< "HTTP/1.0 405 Method Not Allowed\r\n\r\n"
<< int(QAbstractSocket::SocketAccessError);
QTest::newRow("proxy-authentication-too-short")
<< QString() << 0 << "foo"
<< "HTTP/1.0 407 Proxy Authentication Required\r\n\r\n"
<< int(QAbstractSocket::ProxyProtocolError);
QTest::newRow("proxy-authentication-invalid-method")
<< QString() << 0 << "foo"
<< "HTTP/1.0 407 Proxy Authentication Required\r\n"
"Proxy-Authenticate: Frobnicator\r\n\r\n"
<< int(QAbstractSocket::ProxyProtocolError);
QTest::newRow("proxy-authentication-required")
<< QString() << 0 << "foo"
<< "HTTP/1.0 407 Proxy Authentication Required\r\n"
"Proxy-Connection: close\r\n"
"Proxy-Authenticate: Basic, realm=wonderland\r\n\r\n"
<< int(QAbstractSocket::ProxyAuthenticationRequiredError);
QTest::newRow("proxy-authentication-required2")
<< QString() << 0 << "foo"
<< "HTTP/1.0 407 Proxy Authentication Required\r\n"
"Proxy-Connection: keep-alive\r\n"
"Proxy-Authenticate: Basic, realm=wonderland\r\n\r\n"
"\1"
"HTTP/1.0 407 Proxy Authentication Required\r\n"
"Proxy-Authenticate: Basic, realm=wonderland\r\n\r\n"
<< int(QAbstractSocket::ProxyAuthenticationRequiredError);
QTest::newRow("proxy-authentication-required-noclose")
<< QString() << 0 << "foo"
<< "HTTP/1.0 407 Proxy Authentication Required\r\n"
"Proxy-Authenticate: Basic\r\n"
"\r\n"
<< int(QAbstractSocket::ProxyAuthenticationRequiredError);
QTest::newRow("connection-refused") << QString() << 0 << QString()
<< "HTTP/1.0 503 Service Unavailable\r\n\r\n"
<< int(QAbstractSocket::ConnectionRefusedError);
QTest::newRow("host-not-found") << QString() << 0 << QString()
<< "HTTP/1.0 404 Not Found\r\n\r\n"
<< int(QAbstractSocket::HostNotFoundError);
QTest::newRow("weird-http-reply") << QString() << 0 << QString()
<< "HTTP/1.0 206 Partial Content\r\n\r\n"
<< int(QAbstractSocket::ProxyProtocolError);
}
void tst_QHttpSocketEngine::errorTest()
{
QFETCH(QString, hostname);
QFETCH(int, port);
QFETCH(QString, username);
QFETCH(QString, response);
QFETCH(int, expectedError);
MiniHttpServer server(response.toLatin1().split('\1'));
if (hostname.isEmpty()) {
hostname = "127.0.0.1";
port = server.serverPort();
}
QTcpSocket socket;
socket.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, hostname, port, username, username));
socket.connectToHost("0.1.2.3", 12345);
connect(&socket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)),
&QTestEventLoop::instance(), SLOT(exitLoop()));
QTestEventLoop::instance().enterLoop(30);
QVERIFY(!QTestEventLoop::instance().timeout());
QCOMPARE(int(socket.error()), expectedError);
}
//---------------------------------------------------------------------------
void tst_QHttpSocketEngine::simpleConnectToIMAP()
{
QHttpSocketEngine socketDevice;
// Initialize device
QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState);
socketDevice.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::httpProxyServerName(), 3128));
QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::imapServerIp(), 143));
QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState);
QVERIFY(socketDevice.waitForWrite());
QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectedState);
QCOMPARE(socketDevice.peerAddress(), QtNetworkSettings::imapServerIp());
QVERIFY(!socketDevice.localAddress().isNull());
QVERIFY(socketDevice.localPort() > 0);
// Wait for the greeting
QVERIFY(socketDevice.waitForRead());
// Read the greeting
qint64 available = int(socketDevice.bytesAvailable());
QVERIFY(available > 0);
QByteArray array;
array.resize(int(available));
QVERIFY(socketDevice.read(array.data(), array.size()) == available);
// Check that the greeting is what we expect it to be
QVERIFY2(QtNetworkSettings::compareReplyIMAP(array), array.constData());
// Write a logout message
QByteArray array2 = "XXXX LOGOUT\r\n";
QVERIFY(socketDevice.write(array2.data(),
array2.size()) == array2.size());
// Wait for the response
QVERIFY(socketDevice.waitForRead());
available = int(socketDevice.bytesAvailable());
QVERIFY(available > 0);
array.resize(int(available));
QVERIFY(socketDevice.read(array.data(), array.size()) == available);
// Check that the greeting is what we expect it to be
QCOMPARE(array.constData(), "* BYE LOGOUT received\r\nXXXX OK Completed\r\n");
// Wait for the response
QVERIFY(socketDevice.waitForRead());
char c;
QCOMPARE(socketDevice.read(&c, sizeof(c)), qint64(-1));
QCOMPARE(socketDevice.error(), QAbstractSocket::RemoteHostClosedError);
QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState);
}
//---------------------------------------------------------------------------
void tst_QHttpSocketEngine::simpleErrorsAndStates()
{
{
QHttpSocketEngine socketDevice;
// Initialize device
QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
socketDevice.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::httpProxyServerName(), 3128));
QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState);
QVERIFY(!socketDevice.connectToHost(QHostAddress(QtNetworkSettings::socksProxyServerName()), 8088));
QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState);
if (socketDevice.waitForWrite(30000)) {
QVERIFY(socketDevice.state() == QAbstractSocket::ConnectedState ||
socketDevice.state() == QAbstractSocket::UnconnectedState);
} else {
QCOMPARE(socketDevice.error(), QAbstractSocket::SocketTimeoutError);
}
}
}
/*
//---------------------------------------------------------------------------
void tst_QHttpSocketEngine::tcpLoopbackPerformance()
{
QTcpServer server;
// Bind to any port on all interfaces
QVERIFY(server.bind(QHostAddress("0.0.0.0"), 0));
QCOMPARE(server.state(), QAbstractSocket::BoundState);
quint16 port = server.localPort();
// Listen for incoming connections
QVERIFY(server.listen());
QCOMPARE(server.state(), QAbstractSocket::ListeningState);
// Initialize a Tcp socket
QHttpSocketEngine client;
QVERIFY(client.initialize(QAbstractSocket::TcpSocket));
client.setProxy(QHostAddress("80.232.37.158"), 1081);
// Connect to our server
if (!client.connectToHost(QHostAddress("127.0.0.1"), port)) {
QVERIFY(client.waitForWrite());
QVERIFY(client.connectToHost(QHostAddress("127.0.0.1"), port));
}
// The server accepts the connectio
int socketDescriptor = server.accept();
QVERIFY(socketDescriptor > 0);
// A socket device is initialized on the server side, passing the
// socket descriptor from accept(). It's pre-connected.
QSocketLayer serverSocket;
QVERIFY(serverSocket.initialize(socketDescriptor));
QCOMPARE(serverSocket.state(), QAbstractSocket::ConnectedState);
const int messageSize = 1024 * 256;
QByteArray message1(messageSize, '@');
QByteArray answer(messageSize, '@');
QElapsedTimer timer;
timer.start();
qlonglong readBytes = 0;
while (timer.elapsed() < 30000) {
qlonglong written = serverSocket.write(message1.data(), message1.size());
while (written > 0) {
client.waitForRead();
if (client.bytesAvailable() > 0) {
qlonglong readNow = client.read(answer.data(), answer.size());
written -= readNow;
readBytes += readNow;
}
}
}
qDebug("\t\t%.1fMB/%.1fs: %.1fMB/s",
readBytes / (1024.0 * 1024.0),
timer.elapsed() / 1024.0,
(readBytes / (timer.elapsed() / 1000.0)) / (1024 * 1024));
}
*/
void tst_QHttpSocketEngine::tcpSocketBlockingTest()
{
QHttpSocketEngineHandler http;
QTcpSocket socket;
// Connect
socket.connectToHost(QtNetworkSettings::imapServerName(), 143);
QVERIFY(socket.waitForConnected());
QCOMPARE(socket.state(), QTcpSocket::ConnectedState);
// Read greeting
QVERIFY(socket.waitForReadyRead(30000));
QString s = socket.readLine();
QVERIFY2(QtNetworkSettings::compareReplyIMAP(s.toLatin1()), qPrintable(s));
// Write NOOP
QCOMPARE((int) socket.write("1 NOOP\r\n", 8), 8);
if (!socket.canReadLine())
QVERIFY(socket.waitForReadyRead(30000));
// Read response
s = socket.readLine();
QCOMPARE(s.toLatin1().constData(), "1 OK Completed\r\n");
// Write LOGOUT
QCOMPARE((int) socket.write("2 LOGOUT\r\n", 10), 10);
if (!socket.canReadLine())
QVERIFY(socket.waitForReadyRead(30000));
// Read two lines of respose
s = socket.readLine();
QCOMPARE(s.toLatin1().constData(), "* BYE LOGOUT received\r\n");
if (!socket.canReadLine())
QVERIFY(socket.waitForReadyRead(30000));
s = socket.readLine();
QCOMPARE(s.toLatin1().constData(), "2 OK Completed\r\n");
// Close the socket
socket.close();
// Check that it's closed
QCOMPARE(socket.state(), QTcpSocket::UnconnectedState);
}
//----------------------------------------------------------------------------------
void tst_QHttpSocketEngine::tcpSocketNonBlockingTest()
{
QHttpSocketEngineHandler http;
QTcpSocket socket;
connect(&socket, SIGNAL(hostFound()), SLOT(tcpSocketNonBlocking_hostFound()));
connect(&socket, SIGNAL(connected()), SLOT(tcpSocketNonBlocking_connected()));
connect(&socket, SIGNAL(disconnected()), SLOT(tcpSocketNonBlocking_closed()));
connect(&socket, SIGNAL(bytesWritten(qint64)), SLOT(tcpSocketNonBlocking_bytesWritten(qint64)));
connect(&socket, SIGNAL(readyRead()), SLOT(tcpSocketNonBlocking_readyRead()));
tcpSocketNonBlocking_socket = &socket;
// Connect
socket.connectToHost(QtNetworkSettings::imapServerName(), 143);
QVERIFY(socket.state() == QTcpSocket::HostLookupState ||
socket.state() == QTcpSocket::ConnectingState);
QTestEventLoop::instance().enterLoop(30);
if (QTestEventLoop::instance().timeout()) {
QFAIL("Timed out");
}
if (socket.state() == QTcpSocket::ConnectingState) {
QTestEventLoop::instance().enterLoop(30);
if (QTestEventLoop::instance().timeout()) {
QFAIL("Timed out");
}
}
QCOMPARE(socket.state(), QTcpSocket::ConnectedState);
QTestEventLoop::instance().enterLoop(30);
if (QTestEventLoop::instance().timeout()) {
QFAIL("Timed out");
}
// Read greeting
QVERIFY(!tcpSocketNonBlocking_data.isEmpty());
QByteArray data = tcpSocketNonBlocking_data.at(0).toLatin1();
QVERIFY2(QtNetworkSettings::compareReplyIMAP(data), data.constData());
tcpSocketNonBlocking_data.clear();
tcpSocketNonBlocking_totalWritten = 0;
// Write NOOP
QCOMPARE((int) socket.write("1 NOOP\r\n", 8), 8);
QTestEventLoop::instance().enterLoop(30);
if (QTestEventLoop::instance().timeout()) {
QFAIL("Timed out");
}
QCOMPARE(tcpSocketNonBlocking_totalWritten, 8);
QTestEventLoop::instance().enterLoop(30);
if (QTestEventLoop::instance().timeout()) {
QFAIL("Timed out");
}
// Read response
QVERIFY(!tcpSocketNonBlocking_data.isEmpty());
QCOMPARE(tcpSocketNonBlocking_data.at(0).toLatin1().constData(), "1 OK Completed\r\n");
tcpSocketNonBlocking_data.clear();
tcpSocketNonBlocking_totalWritten = 0;
// Write LOGOUT
QCOMPARE((int) socket.write("2 LOGOUT\r\n", 10), 10);
QTestEventLoop::instance().enterLoop(30);
if (QTestEventLoop::instance().timeout()) {
QFAIL("Timed out");
}
QCOMPARE(tcpSocketNonBlocking_totalWritten, 10);
// Wait for greeting
QTestEventLoop::instance().enterLoop(30);
if (QTestEventLoop::instance().timeout()) {
QFAIL("Timed out");
}
// Read two lines of respose
QCOMPARE(tcpSocketNonBlocking_data.at(0).toLatin1().constData(), "* BYE LOGOUT received\r\n");
QCOMPARE(tcpSocketNonBlocking_data.at(1).toLatin1().constData(), "2 OK Completed\r\n");
tcpSocketNonBlocking_data.clear();
// Close the socket
socket.close();
// Check that it's closed
QCOMPARE(socket.state(), QTcpSocket::UnconnectedState);
}
void tst_QHttpSocketEngine::tcpSocketNonBlocking_hostFound()
{
QTestEventLoop::instance().exitLoop();
}
void tst_QHttpSocketEngine::tcpSocketNonBlocking_connected()
{
QTestEventLoop::instance().exitLoop();
}
void tst_QHttpSocketEngine::tcpSocketNonBlocking_readyRead()
{
while (tcpSocketNonBlocking_socket->canReadLine())
tcpSocketNonBlocking_data.append(tcpSocketNonBlocking_socket->readLine());
QTestEventLoop::instance().exitLoop();
}
void tst_QHttpSocketEngine::tcpSocketNonBlocking_bytesWritten(qint64 written)
{
tcpSocketNonBlocking_totalWritten += written;
QTestEventLoop::instance().exitLoop();
}
void tst_QHttpSocketEngine::tcpSocketNonBlocking_closed()
{
}
//----------------------------------------------------------------------------------
void tst_QHttpSocketEngine::downloadBigFile()
{
QHttpSocketEngineHandler http;
if (tmpSocket)
delete tmpSocket;
tmpSocket = new QTcpSocket;
connect(tmpSocket, SIGNAL(connected()), SLOT(exitLoopSlot()));
connect(tmpSocket, SIGNAL(readyRead()), SLOT(downloadBigFileSlot()));
tmpSocket->connectToHost(QtNetworkSettings::httpServerName(), 80);
QTestEventLoop::instance().enterLoop(30);
if (QTestEventLoop::instance().timeout())
QFAIL("Network operation timed out");
QByteArray hostName = QtNetworkSettings::httpServerName().toLatin1();
QCOMPARE(tmpSocket->state(), QAbstractSocket::ConnectedState);
QVERIFY(tmpSocket->write("GET /qtest/mediumfile HTTP/1.0\r\n") > 0);
QVERIFY(tmpSocket->write("Host: ") > 0);
QVERIFY(tmpSocket->write(hostName.data()) > 0);
QVERIFY(tmpSocket->write("\r\n") > 0);
QVERIFY(tmpSocket->write("\r\n") > 0);
bytesAvailable = 0;
QElapsedTimer stopWatch;
stopWatch.start();
QTestEventLoop::instance().enterLoop(60);
if (QTestEventLoop::instance().timeout())
QFAIL("Network operation timed out");
QVERIFY(bytesAvailable >= 10000000);
QCOMPARE(tmpSocket->state(), QAbstractSocket::ConnectedState);
qDebug("\t\t%.1fMB/%.1fs: %.1fMB/s",
bytesAvailable / (1024.0 * 1024.0),
stopWatch.elapsed() / 1024.0,
(bytesAvailable / (stopWatch.elapsed() / 1000.0)) / (1024 * 1024));
delete tmpSocket;
tmpSocket = 0;
}
void tst_QHttpSocketEngine::exitLoopSlot()
{
QTestEventLoop::instance().exitLoop();
}
void tst_QHttpSocketEngine::downloadBigFileSlot()
{
bytesAvailable += tmpSocket->readAll().size();
if (bytesAvailable >= 10000000)
QTestEventLoop::instance().exitLoop();
}
void tst_QHttpSocketEngine::passwordAuth()
{
QHttpSocketEngine socketDevice;
// Initialize device
QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState);
socketDevice.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::httpProxyServerName(), 3128, "qsockstest", "password"));
QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::imapServerIp(), 143));
QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState);
QVERIFY(socketDevice.waitForWrite());
QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectedState);
QCOMPARE(socketDevice.peerAddress(), QtNetworkSettings::imapServerIp());
// Wait for the greeting
QVERIFY(socketDevice.waitForRead());
// Read the greeting
qint64 available = socketDevice.bytesAvailable();
QVERIFY(available > 0);
QByteArray array;
array.resize(available);
QVERIFY(socketDevice.read(array.data(), array.size()) == available);
// Check that the greeting is what we expect it to be
QVERIFY2(QtNetworkSettings::compareReplyIMAP(array), array.constData());
// Write a logout message
QByteArray array2 = "XXXX LOGOUT\r\n";
QVERIFY(socketDevice.write(array2.data(),
array2.size()) == array2.size());
// Wait for the response
QVERIFY(socketDevice.waitForRead());
available = socketDevice.bytesAvailable();
QVERIFY(available > 0);
array.resize(available);
QVERIFY(socketDevice.read(array.data(), array.size()) == available);
// Check that the greeting is what we expect it to be
QCOMPARE(array.constData(), "* BYE LOGOUT received\r\nXXXX OK Completed\r\n");
// Wait for the response
QVERIFY(socketDevice.waitForRead());
char c;
QVERIFY(socketDevice.read(&c, sizeof(c)) == -1);
QCOMPARE(socketDevice.error(), QAbstractSocket::RemoteHostClosedError);
QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState);
}
//----------------------------------------------------------------------------------
void tst_QHttpSocketEngine::ensureEofTriggersNotification()
{
QList<QByteArray> serverData;
// Set the handshake and server response data
serverData << "HTTP/1.0 200 Connection established\r\n\r\n" << "0";
MiniHttpServer server(serverData);
QTcpSocket socket;
connect(&socket, SIGNAL(connected()), SLOT(exitLoopSlot()));
socket.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, server.serverAddress().toString(),
server.serverPort()));
socket.connectToHost("0.1.2.3", 12345);
QTestEventLoop::instance().enterLoop(5);
if (QTestEventLoop::instance().timeout())
QFAIL("Connect timed out");
QCOMPARE(socket.state(), QTcpSocket::ConnectedState);
// Disable read notification on server response
socket.setReadBufferSize(1);
socket.putChar(0);
// Wait for the response
connect(&socket, SIGNAL(readyRead()), SLOT(exitLoopSlot()));
QTestEventLoop::instance().enterLoop(5);
if (QTestEventLoop::instance().timeout())
QFAIL("Read timed out");
QCOMPARE(socket.state(), QTcpSocket::ConnectedState);
QCOMPARE(socket.bytesAvailable(), 1);
// Trigger a read notification
socket.readAll();
// Check for pending EOF at input
QCOMPARE(socket.bytesAvailable(), 0);
QCOMPARE(socket.state(), QTcpSocket::ConnectedState);
// Try to read EOF
connect(&socket, SIGNAL(disconnected()), SLOT(exitLoopSlot()));
QTestEventLoop::instance().enterLoop(5);
if (QTestEventLoop::instance().timeout())
QFAIL("Disconnect timed out");
// Check that it's closed
QCOMPARE(socket.state(), QTcpSocket::UnconnectedState);
}
QTEST_MAIN(tst_QHttpSocketEngine)
#include "tst_qhttpsocketengine.moc"

View File

@ -0,0 +1,10 @@
# QTBUG-87387
[fullPath]
android
[processConnection]
android
windows
[verifySocketOptions]
android
[threadedConnection]
windows

View File

@ -0,0 +1,15 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
# add_subdirectory(test) # special case remove
add_subdirectory(socketprocess)
qt_internal_add_test(tst_qlocalsocket
SOURCES
tst_qlocalsocket.cpp
DEFINES
QLOCALSERVER_DEBUG
QLOCALSOCKET_DEBUG
LIBRARIES
Qt::Network
)
add_dependencies(tst_qlocalsocket socketprocess)

View File

@ -0,0 +1,15 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## socketprocess Binary:
#####################################################################
qt_internal_add_executable(socketprocess
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
SOURCES
main.cpp
LIBRARIES
Qt::Network
Qt::Test
)

View File

@ -0,0 +1,119 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <qcoreapplication.h>
#include <qelapsedtimer.h>
#include <qeventloop.h>
#include <qlocalsocket.h>
#include <qlocalserver.h>
#include <qtimer.h>
const QString serverName = QStringLiteral("qlocalsocket_autotest");
const QByteArray testData("test");
bool runServer(int numberOfConnections)
{
QLocalServer *server = new QLocalServer(qApp);
if (!server->removeServer(serverName)) {
fprintf(stderr, "server: cannot remove server: %s\n", qPrintable(server->errorString()));
return false;
}
printf("server: listen on \"%s\"\n", qPrintable(serverName));
if (!server->listen(serverName)) {
fprintf(stderr, "server: listen failed: %s\n", qPrintable(server->errorString()));
return false;
}
for (int i = 1; i <= numberOfConnections; ++i) {
printf("server: wait for connection %d\n", i);
if (!server->waitForNewConnection(30000)) {
fprintf(stderr, "server: waitForNewConnection failed: %s\n",
qPrintable(server->errorString()));
return false;
}
QLocalSocket *socket = server->nextPendingConnection();
printf("server: writing \"%s\"\n", testData.data());
socket->write(testData);
if (!socket->waitForBytesWritten()) {
fprintf(stderr, "server: waitForBytesWritten failed: %s\n",
qPrintable(socket->errorString()));
return false;
}
printf("server: data written\n");
if (socket->error() != QLocalSocket::UnknownSocketError) {
fprintf(stderr, "server: socket error %d\n", socket->error());
return false;
}
}
return true;
}
bool runClient()
{
QLocalSocket socket;
printf("client: connecting to \"%s\"\n", qPrintable(serverName));
QElapsedTimer connectTimer;
connectTimer.start();
forever {
socket.connectToServer(serverName, QLocalSocket::ReadWrite);
if (socket.waitForConnected())
break;
if (socket.error() == QLocalSocket::ServerNotFoundError
|| socket.error() == QLocalSocket::ConnectionRefusedError) {
if (connectTimer.elapsed() > 5000) {
fprintf(stderr, "client: server not found or connection refused. Giving up.\n");
return false;
}
printf("client: server not found. Trying again...\n");
QEventLoop eventLoop;
QTimer::singleShot(500, &eventLoop, SLOT(quit()));
eventLoop.exec();
continue;
}
fprintf(stderr, "client: waitForConnected failed: %s\n",
qPrintable(socket.errorString()));
return false;
}
printf("client: connected\n");
if (!socket.waitForReadyRead()) {
fprintf(stderr, "client: waitForReadyRead failed: %s\n",
qPrintable(socket.errorString()));
return false;
}
printf("client: data is available for reading\n");
const QByteArray data = socket.readLine();
printf("client: received \"%s\"\n", data.data());
if (data != testData) {
fprintf(stderr, "client: received unexpected data\n");
return false;
}
return true;
}
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
if (argc < 2)
return EXIT_FAILURE;
if (strcmp(argv[1], "--server") == 0) {
if (argc < 3) {
fprintf(stderr, "--server needs the number of incoming connections\n");
return EXIT_FAILURE;
}
bool ok;
int n = QByteArray(argv[2]).toInt(&ok);
if (!ok) {
fprintf(stderr, "Cannot convert %s to a number.\n", argv[2]);
return EXIT_FAILURE;
}
if (!runServer(n))
return EXIT_FAILURE;
} else if (strcmp(argv[1], "--client") == 0) {
if (!runClient())
return EXIT_FAILURE;
} else {
fprintf(stderr, "unknown command line option: %s\n", argv[1]);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,13 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qsctpsocket Test:
#####################################################################
qt_internal_add_test(tst_qsctpsocket
SOURCES
tst_qsctpsocket.cpp
LIBRARIES
Qt::Network
)

View File

@ -0,0 +1,458 @@
// Copyright (C) 2016 Alex Trotsenko <alex1973tr@gmail.com>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QTest>
#include <QDebug>
#include <QTestEventLoop>
#include <QByteArray>
#include <QString>
#include <QHostAddress>
#include <QHostInfo>
#include <QNetworkInterface>
#include <QTime>
#include <QSctpSocket>
#include <QSctpServer>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#define SOCKET int
#define INVALID_SOCKET -1
class tst_QSctpSocket : public QObject
{
Q_OBJECT
public:
static void enterLoop(int secs)
{
++loopLevel;
QTestEventLoop::instance().enterLoop(secs);
--loopLevel;
}
static void exitLoop()
{
// Safe exit - if we aren't in an event loop, don't
// exit one.
if (loopLevel > 0)
QTestEventLoop::instance().exitLoop();
}
static bool timeout()
{
return QTestEventLoop::instance().timeout();
}
private slots:
void constructing();
void bind_data();
void bind();
void setInvalidSocketDescriptor();
void setSocketDescriptor();
void socketDescriptor();
void hostNotFound();
void connecting();
void readAndWrite();
void loop_data();
void loop();
void loopInTCPMode_data();
void loopInTCPMode();
void readDatagramAfterClose();
void clientSendDataOnDelayedDisconnect();
protected slots:
void exitLoopSlot();
private:
static int loopLevel;
};
int tst_QSctpSocket::loopLevel = 0;
//----------------------------------------------------------------------------------
void tst_QSctpSocket::constructing()
{
QSctpSocket socket;
// Check the initial state of the QSctpSocket.
QCOMPARE(socket.state(), QAbstractSocket::UnconnectedState);
QVERIFY(socket.isSequential());
QVERIFY(!socket.isOpen());
QVERIFY(!socket.isValid());
QCOMPARE(socket.socketType(), QAbstractSocket::SctpSocket);
QCOMPARE(socket.maximumChannelCount(), 0);
QCOMPARE(socket.readChannelCount(), 0);
QCOMPARE(socket.writeChannelCount(), 0);
char c;
QCOMPARE(socket.getChar(&c), false);
QCOMPARE(socket.bytesAvailable(), Q_INT64_C(0));
QCOMPARE(socket.canReadLine(), false);
QCOMPARE(socket.readLine(), QByteArray());
QCOMPARE(socket.socketDescriptor(), qintptr(-1));
QCOMPARE(int(socket.localPort()), 0);
QVERIFY(socket.localAddress() == QHostAddress());
QCOMPARE(int(socket.peerPort()), 0);
QVERIFY(socket.peerAddress() == QHostAddress());
QCOMPARE(socket.error(), QAbstractSocket::UnknownSocketError);
QCOMPARE(socket.errorString(), QString("Unknown error"));
}
//----------------------------------------------------------------------------------
void tst_QSctpSocket::bind_data()
{
QTest::addColumn<QString>("stringAddr");
QTest::addColumn<bool>("successExpected");
QTest::addColumn<QString>("stringExpectedLocalAddress");
// iterate all interfaces, add all addresses on them as test data
QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
for (const QNetworkInterface &interface : interfaces) {
if (!interface.isValid())
continue;
for (const QNetworkAddressEntry &entry : interface.addressEntries()) {
if (entry.ip().isInSubnet(QHostAddress::parseSubnet("fe80::/10"))
|| entry.ip().isInSubnet(QHostAddress::parseSubnet("169.254/16")))
continue; // link-local bind will fail, at least on Linux, so skip it.
QString ip(entry.ip().toString());
QTest::newRow(ip.toLatin1().constData()) << ip << true << ip;
}
}
// additionally, try bind to known-bad addresses, and make sure this doesn't work
// these ranges are guaranteed to be reserved for 'documentation purposes',
// and thus, should be unused in the real world. Not that I'm assuming the
// world is full of competent administrators, or anything.
QStringList knownBad;
knownBad << "198.51.100.1";
knownBad << "2001:0DB8::1";
foreach (const QString &badAddress, knownBad) {
QTest::newRow(badAddress.toLatin1().constData()) << badAddress << false << QString();
}
}
// Testing bind function
void tst_QSctpSocket::bind()
{
QFETCH(QString, stringAddr);
QFETCH(bool, successExpected);
QFETCH(QString, stringExpectedLocalAddress);
QHostAddress addr(stringAddr);
QHostAddress expectedLocalAddress(stringExpectedLocalAddress);
QSctpSocket socket;
qDebug() << "Binding " << addr;
if (successExpected)
QVERIFY2(socket.bind(addr), qPrintable(socket.errorString()));
else
QVERIFY(!socket.bind(addr));
QCOMPARE(socket.localAddress(), expectedLocalAddress);
}
//----------------------------------------------------------------------------------
void tst_QSctpSocket::setInvalidSocketDescriptor()
{
QSctpSocket socket;
QCOMPARE(socket.socketDescriptor(), qintptr(INVALID_SOCKET));
QVERIFY(!socket.setSocketDescriptor(-5, QAbstractSocket::UnconnectedState));
QCOMPARE(socket.socketDescriptor(), qintptr(INVALID_SOCKET));
QCOMPARE(socket.error(), QAbstractSocket::UnsupportedSocketOperationError);
}
//----------------------------------------------------------------------------------
void tst_QSctpSocket::setSocketDescriptor()
{
QSctpServer server;
server.setMaximumChannelCount(16);
QVERIFY(server.listen());
SOCKET sock = ::socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
QVERIFY(sock != INVALID_SOCKET);
QSctpSocket socket;
QVERIFY(socket.setSocketDescriptor(sock, QAbstractSocket::UnconnectedState));
QCOMPARE(socket.socketDescriptor(), qintptr(sock));
QCOMPARE(socket.readChannelCount(), 0);
QCOMPARE(socket.writeChannelCount(), 0);
socket.connectToHost(QHostAddress::LocalHost, server.serverPort());
QVERIFY(socket.waitForConnected(3000));
QVERIFY(server.waitForNewConnection(3000));
QCOMPARE(socket.readChannelCount(), server.maximumChannelCount());
QVERIFY(socket.writeChannelCount() <= server.maximumChannelCount());
QSctpSocket *acceptedSocket = server.nextPendingDatagramConnection();
QVERIFY(acceptedSocket);
QCOMPARE(acceptedSocket->readChannelCount(), socket.writeChannelCount());
QCOMPARE(acceptedSocket->writeChannelCount(), socket.readChannelCount());
}
//----------------------------------------------------------------------------------
void tst_QSctpSocket::socketDescriptor()
{
QSctpSocket socket;
QSctpServer server;
QVERIFY(server.listen());
QCOMPARE(socket.socketDescriptor(), qintptr(INVALID_SOCKET));
socket.connectToHost(QHostAddress::LocalHost, server.serverPort());
QVERIFY(server.waitForNewConnection(3000));
if (socket.state() != QAbstractSocket::ConnectedState) {
QVERIFY((socket.state() == QAbstractSocket::HostLookupState
&& socket.socketDescriptor() == INVALID_SOCKET)
|| socket.state() == QAbstractSocket::ConnectingState);
QVERIFY(socket.waitForConnected(3000));
QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
}
QVERIFY(socket.socketDescriptor() != INVALID_SOCKET);
}
//----------------------------------------------------------------------------------
void tst_QSctpSocket::hostNotFound()
{
QSctpSocket socket;
socket.connectToHost("nosuchserver.qt-project.org", 80);
QVERIFY(!socket.waitForConnected(3000));
QCOMPARE(socket.state(), QTcpSocket::UnconnectedState);
QCOMPARE(socket.error(), QAbstractSocket::HostNotFoundError);
}
// Testing connect function
void tst_QSctpSocket::connecting()
{
QSctpServer server;
QVERIFY(server.listen());
QSctpSocket socket;
socket.connectToHost(QHostAddress::LocalHost, server.serverPort());
QVERIFY(socket.waitForConnected(3000));
QVERIFY(server.waitForNewConnection(3000));
QSctpSocket *acceptedSocket = server.nextPendingDatagramConnection();
QVERIFY(acceptedSocket);
QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
QCOMPARE(acceptedSocket->state(), QAbstractSocket::ConnectedState);
QCOMPARE(socket.readChannelCount(), acceptedSocket->readChannelCount());
QCOMPARE(socket.writeChannelCount(),acceptedSocket->writeChannelCount());
}
// Testing read/write functions
void tst_QSctpSocket::readAndWrite()
{
QSctpServer server;
QVERIFY(server.listen());
QSctpSocket socket;
socket.connectToHost(QHostAddress::LocalHost, server.serverPort());
QVERIFY(socket.waitForConnected(3000));
QVERIFY(server.waitForNewConnection(3000));
QSctpSocket *acceptedSocket = server.nextPendingDatagramConnection();
QVERIFY(acceptedSocket);
QByteArray ba(1000, 1);
QVERIFY(acceptedSocket->writeDatagram(ba));
QVERIFY(acceptedSocket->waitForBytesWritten(3000));
QVERIFY(socket.waitForReadyRead(3000));
QNetworkDatagram datagram = socket.readDatagram();
QVERIFY(datagram.isValid());
QCOMPARE(datagram.data(), ba);
QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
QCOMPARE(socket.error(), QAbstractSocket::UnknownSocketError);
QCOMPARE(socket.errorString(), QString("Unknown error"));
QCOMPARE(acceptedSocket->state(), QAbstractSocket::ConnectedState);
QCOMPARE(acceptedSocket->error(), QAbstractSocket::UnknownSocketError);
QCOMPARE(acceptedSocket->errorString(), QString("Unknown error"));
}
//----------------------------------------------------------------------------------
void tst_QSctpSocket::loop_data()
{
QTest::addColumn<QByteArray>("peterDatagram");
QTest::addColumn<QByteArray>("paulDatagram");
QTest::addColumn<int>("peterChannel");
QTest::addColumn<int>("paulChannel");
QTest::newRow("\"Almond!\" | \"Joy!\"") << QByteArray("Almond!") << QByteArray("Joy!") << 0 << 0;
QTest::newRow("\"A\" | \"B\"") << QByteArray("A") << QByteArray("B") << 1 << 1;
QTest::newRow("\"AB\" | \"B\"") << QByteArray("AB") << QByteArray("B") << 0 << 1;
QTest::newRow("\"AB\" | \"BB\"") << QByteArray("AB") << QByteArray("BB") << 1 << 0;
QTest::newRow("\"A\\0B\" | \"B\\0B\"") << QByteArray::fromRawData("A\0B", 3) << QByteArray::fromRawData("B\0B", 3) << 0 << 1;
QTest::newRow("BigDatagram") << QByteArray(600, '@') << QByteArray(600, '@') << 1 << 0;
}
void tst_QSctpSocket::loop()
{
QFETCH(QByteArray, peterDatagram);
QFETCH(QByteArray, paulDatagram);
QFETCH(int, peterChannel);
QFETCH(int, paulChannel);
QSctpServer server;
server.setMaximumChannelCount(10);
QVERIFY(server.listen());
QSctpSocket peter;
peter.setMaximumChannelCount(10);
peter.connectToHost(QHostAddress::LocalHost, server.serverPort());
QVERIFY(peter.waitForConnected(3000));
QVERIFY(server.waitForNewConnection(3000));
QSctpSocket *paul = server.nextPendingDatagramConnection();
QVERIFY(paul);
peter.setCurrentWriteChannel(peterChannel);
QVERIFY(peter.writeDatagram(peterDatagram));
paul->setCurrentWriteChannel(paulChannel);
QVERIFY(paul->writeDatagram(paulDatagram));
QVERIFY(peter.flush());
QVERIFY(paul->flush());
peter.setCurrentReadChannel(paulChannel);
QVERIFY(peter.waitForReadyRead(3000));
QCOMPARE(peter.bytesAvailable(), paulDatagram.size());
QCOMPARE(peter.readDatagram().data(), paulDatagram);
paul->setCurrentReadChannel(peterChannel);
QVERIFY(paul->waitForReadyRead(3000));
QCOMPARE(paul->bytesAvailable(), peterDatagram.size());
QCOMPARE(paul->readDatagram().data(), peterDatagram);
}
//----------------------------------------------------------------------------------
void tst_QSctpSocket::loopInTCPMode_data()
{
QTest::addColumn<QByteArray>("peterDatagram");
QTest::addColumn<QByteArray>("paulDatagram");
QTest::newRow("\"Almond!\" | \"Joy!\"") << QByteArray("Almond!") << QByteArray("Joy!");
QTest::newRow("\"A\" | \"B\"") << QByteArray("A") << QByteArray("B");
QTest::newRow("\"AB\" | \"B\"") << QByteArray("AB") << QByteArray("B");
QTest::newRow("\"AB\" | \"BB\"") << QByteArray("AB") << QByteArray("BB");
QTest::newRow("\"A\\0B\" | \"B\\0B\"") << QByteArray::fromRawData("A\0B", 3) << QByteArray::fromRawData("B\0B", 3);
QTest::newRow("BigDatagram") << QByteArray(600, '@') << QByteArray(600, '@');
}
void tst_QSctpSocket::loopInTCPMode()
{
QFETCH(QByteArray, peterDatagram);
QFETCH(QByteArray, paulDatagram);
QSctpServer server;
server.setMaximumChannelCount(-1);
QVERIFY(server.listen());
QSctpSocket peter;
peter.setMaximumChannelCount(-1);
peter.connectToHost(QHostAddress::LocalHost, server.serverPort());
QVERIFY(peter.waitForConnected(3000));
QVERIFY(server.waitForNewConnection(3000));
QTcpSocket *paul = server.nextPendingConnection();
QVERIFY(paul);
QCOMPARE(peter.write(peterDatagram), qint64(peterDatagram.size()));
QCOMPARE(paul->write(paulDatagram), qint64(paulDatagram.size()));
QVERIFY(peter.flush());
QVERIFY(paul->flush());
QVERIFY(peter.waitForReadyRead(3000));
QVERIFY(paul->waitForReadyRead(3000));
QCOMPARE(peter.bytesAvailable(), paulDatagram.size());
QByteArray peterBuffer = peter.readAll();
QCOMPARE(paul->bytesAvailable(), peterDatagram.size());
QByteArray paulBuffer = paul->readAll();
QCOMPARE(peterBuffer, paulDatagram);
QCOMPARE(paulBuffer, peterDatagram);
}
//----------------------------------------------------------------------------------
void tst_QSctpSocket::exitLoopSlot()
{
exitLoop();
}
//----------------------------------------------------------------------------------
void tst_QSctpSocket::readDatagramAfterClose()
{
QSctpServer server;
QVERIFY(server.listen());
QSctpSocket socket;
socket.connectToHost(QHostAddress::LocalHost, server.serverPort());
QVERIFY(socket.waitForConnected(3000));
QVERIFY(server.waitForNewConnection(3000));
QSctpSocket *acceptedSocket = server.nextPendingDatagramConnection();
QVERIFY(acceptedSocket);
connect(&socket, &QIODevice::readyRead, this, &tst_QSctpSocket::exitLoopSlot);
QByteArray ba(1000, 1);
QVERIFY(acceptedSocket->writeDatagram(ba));
enterLoop(10);
if (timeout())
QFAIL("Network operation timed out");
QCOMPARE(socket.bytesAvailable(), ba.size());
socket.close();
QVERIFY(!socket.readDatagram().isValid());
}
// Test buffered socket properly send data on delayed disconnect
void tst_QSctpSocket::clientSendDataOnDelayedDisconnect()
{
QSctpServer server;
QVERIFY(server.listen());
// Connect to server, write data and close socket
QSctpSocket socket;
socket.connectToHost(QHostAddress::LocalHost, server.serverPort());
QVERIFY(socket.waitForConnected(3000));
QByteArray sendData("GET /\r\n");
sendData = sendData.repeated(1000);
QVERIFY(socket.writeDatagram(sendData));
socket.close();
QCOMPARE(socket.state(), QAbstractSocket::ClosingState);
QVERIFY(socket.waitForDisconnected(3000));
QVERIFY(server.waitForNewConnection(3000));
QSctpSocket *acceptedSocket = server.nextPendingDatagramConnection();
QVERIFY(acceptedSocket);
QVERIFY(acceptedSocket->waitForReadyRead(3000));
QNetworkDatagram datagram = acceptedSocket->readDatagram();
QVERIFY(datagram.isValid());
QCOMPARE(datagram.data(), sendData);
}
QTEST_MAIN(tst_QSctpSocket)
#include "tst_qsctpsocket.moc"

View File

@ -0,0 +1,13 @@
[udpTest]
*
[passwordAuth]
ubuntu
# QTBUG-101274
qnx ci
# QTBUG-74162
[passwordAuth2]
ubuntu
[downloadBigFile]
windows-10 msvc-2015
windows-7sp1

View File

@ -0,0 +1,29 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
if(NOT QT_FEATURE_private_tests)
return()
endif()
#####################################################################
## tst_qsocks5socketengine Test:
#####################################################################
qt_internal_add_test(tst_qsocks5socketengine
SOURCES
tst_qsocks5socketengine.cpp
LIBRARIES
Qt::CorePrivate
Qt::NetworkPrivate
QT_TEST_SERVER_LIST "danted" "apache2" "cyrus"
)
## Scopes:
#####################################################################
# QT_TEST_SERVER_LIST = "danted" "apache2" "cyrus"
qt_internal_extend_target(tst_qsocks5socketengine CONDITION WIN32
LIBRARIES
ws2_32
)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
[listenWhileListening:WithSocks5Proxy]
linux
windows
[ipv6Server]
windows-7sp1
windows-10 msvc-2017
[ipv6Server:WithoutProxy]
windows
osx
[serverAddress]
# QTBUG-103056
qnx
windows-7sp1
windows-10
[linkLocal]
macos arm

View File

@ -0,0 +1,5 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
add_subdirectory(crashingServer)
add_subdirectory(test)

View File

@ -0,0 +1,17 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## crashingServer Binary:
#####################################################################
qt_internal_add_executable(crashingServer
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
SOURCES
main.cpp
LIBRARIES
Qt::Network
)
## Scopes:
#####################################################################

View File

@ -0,0 +1,58 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtCore>
#include <QtNetwork>
#if defined(Q_OS_WIN) && defined(Q_CC_MSVC)
# include <crtdbg.h>
#endif
#ifdef Q_OS_UNIX
# include <sys/resource.h>
# include <unistd.h>
#endif
int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN) && defined(Q_CC_MSVC)
// Windows: Suppress crash notification dialog.
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
#elif defined(RLIMIT_CORE)
// Unix: set our core dump limit to zero to request no dialogs.
if (struct rlimit rlim; getrlimit(RLIMIT_CORE, &rlim) == 0) {
rlim.rlim_cur = 0;
setrlimit(RLIMIT_CORE, &rlim);
}
#endif
QCoreApplication app(argc, argv);
if (argc < 1) {
fprintf(stderr, "Need a port number\n");
return 1;
}
int port = QByteArrayView(argv[1]).toInt();
QTcpServer server;
if (!server.listen(QHostAddress::LocalHost, port)) {
fprintf(stderr, "Failed to listen: %s\n", server.errorString().toLatin1().constData());
if (server.serverError() == QTcpSocket::AddressInUseError) {
// let's see if we can find the process that would be holding this
// still open
#ifdef Q_OS_LINUX
static const char *ss_args[] = {
"ss", "-nap", "sport", "=", argv[1], nullptr
};
dup2(STDERR_FILENO, STDOUT_FILENO);
execvp(ss_args[0], const_cast<char **>(ss_args));
#endif
}
return 1;
}
printf("Listening\n");
fflush(stdout);
server.waitForNewConnection(5000);
qFatal("Crash");
return 0;
}

View File

@ -0,0 +1,27 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qtcpserver Test:
#####################################################################
qt_internal_add_test(tst_qtcpserver
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../"
SOURCES
../tst_qtcpserver.cpp
LIBRARIES
Qt::Network
QT_TEST_SERVER_LIST "danted" "cyrus" "squid" "ftp-proxy"
)
add_dependencies(tst_qtcpserver
crashingServer
)
## Scopes:
#####################################################################
qt_internal_extend_target(tst_qtcpserver CONDITION WIN32
LIBRARIES
ws2_32
)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,77 @@
[timeoutConnect:ip]
windows
# QTBUG-101274
[timeoutConnect:WithSocks5Proxy:ip]
qnx ci
[timeoutConnect:WithSocks5ProxyAuth:ip]
qnx ci
[timeoutConnect:WithHttpProxy:ip]
qnx ci
[timeoutConnect:WithHttpProxyBasicAuth:ip]
qnx ci
[timeoutConnect:WithSocks5Proxy SSL:ip]
qnx ci
[timeoutConnect:WithSocks5AuthProxy SSL:ip]
qnx ci
[timeoutConnect:WithHttpProxy SSL:ip]
qnx ci
[timeoutConnect:WithHttpProxyBasicAuth SSL:ip]
qnx ci
[suddenRemoteDisconnect:WithoutProxy:Qt4 Client <-> Qt4 Server]
qnx ci
# QTBUG-66247
[delayedClose:WithSocks5Proxy]
windows-10 gcc developer-build
[delayedClose:WithSocks5Proxy SSL]
windows-10 gcc developer-build
[partialRead:WithSocks5Proxy]
windows-10 gcc developer-build
[partialRead:WithSocks5Proxy SSL]
windows-10 gcc developer-build
[unget:WithSocks5Proxy]
windows-10 gcc developer-build
[unget:WithSocks5Proxy SSL]
windows-10 gcc developer-build
[readAllAfterClose:WithSocks5Proxy]
windows-10 gcc developer-build
[readAllAfterClose:WithSocks5Proxy SSL]
windows-10 gcc developer-build
[openCloseOpenClose:WithSocks5Proxy]
windows-10 gcc developer-build
[openCloseOpenClose:WithSocks5Proxy SSL]
windows-10 gcc developer-build
[connectDisconnectConnectDisconnect:WithSocks5Proxy]
windows-10 gcc developer-build
[connectDisconnectConnectDisconnect:WithSocks5Proxy SSL]
windows-10 gcc developer-build
[downloadBigFile:WithSocks5Proxy]
windows-10 gcc developer-build
[downloadBigFile:WithSocks5Proxy SSL]
windows-10 gcc developer-build
[connectToHostError:WithoutProxy:localhost no service]
windows-10 gcc developer-build
[connectToHostError:WithSocks5Proxy:localhost no service]
windows-10 gcc developer-build
[connectToHostError:WithSocks5ProxyAuth:localhost no service]
windows-10 gcc developer-build
[connectToHostError:WithHttpProxy:localhost no service]
windows-10 gcc developer-build
[connectToHostError:WithHttpProxyBasicAuth:localhost no service]
windows-10 gcc developer-build
[connectToHostError:WithoutProxy SSL:localhost no service]
windows-10 gcc developer-build
[connectToHostError:WithSocks5Proxy SSL:localhost no service]
windows-10 gcc developer-build
[connectToHostError:WithSocks5AuthProxy SSL:localhost no service]
windows-10 gcc developer-build
[connectToHostError:WithHttpProxy SSL:localhost no service]
windows-10 gcc developer-build
[connectToHostError:WithHttpProxyBasicAuth SSL:localhost no service]
windows-10 gcc developer-build
[bind]
macos arm
# QTBUG-101274
[bindThenResolveHost:WithoutProxy:first-fail]
qnx ci
[bindThenResolveHost:WithoutProxy SSL:first-fail]
qnx ci

View File

@ -0,0 +1,10 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
if(NOT QT_FEATURE_private_tests)
return()
endif()
add_subdirectory(test)
if(NOT VXWORKS)
add_subdirectory(stressTest)
endif()

View File

@ -0,0 +1,16 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## stressTest Binary:
#####################################################################
qt_internal_add_executable(stressTest
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
SOURCES
Test.cpp Test.h
main.cpp
LIBRARIES
Qt::Network
Qt::Test
)

View File

@ -0,0 +1,109 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
// Qt
#include <QByteArray>
#include <QCoreApplication>
#include <QDataStream>
#include <QTimer>
// Test
#include "Test.h"
//------------------------------------------------------------------------------
My4Socket::My4Socket(QObject *parent)
: QTcpSocket(parent), safeShutDown(false)
{
connect(this, SIGNAL(readyRead()), this, SLOT(read()));
connect(this, SIGNAL(disconnected()), this, SLOT(closed()));
}
//------------------------------------------------------------------------------
void My4Socket::read(void)
{
QDataStream in(this);
quint32 num = 0;
quint32 reply = 0;
while (bytesAvailable()) {
in >> num;
if (num == 42) {
safeShutDown = true;
qDebug("SUCCESS");
QCoreApplication::instance()->quit();
return;
}
reply = num + 1;
if (reply == 42)
++reply;
}
// Reply with a bigger number
sendTest(reply);
}
//------------------------------------------------------------------------------
void My4Socket::closed(void)
{
if (!safeShutDown)
qDebug("FAILED");
QCoreApplication::instance()->quit();
}
//------------------------------------------------------------------------------
void My4Socket::sendTest(quint32 num)
{
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out << num;
write(block, block.size());
}
//------------------------------------------------------------------------------
My4Server::My4Server(QObject *parent)
: QTcpServer(parent)
{
if (listen(QHostAddress::Any, 7700))
qDebug("qt4server");
QTimer::singleShot(5000, this, SLOT(stopServer()));
}
//------------------------------------------------------------------------------
void My4Server::incomingConnection(qintptr socketId)
{
m_socket = new My4Socket(this);
m_socket->setSocketDescriptor(socketId);
}
//------------------------------------------------------------------------------
void My4Server::stopServer()
{
if (m_socket) {
qDebug("SUCCESS");
m_socket->safeShutDown = true;
m_socket->sendTest(42);
} else {
QCoreApplication::instance()->quit();
}
}
//------------------------------------------------------------------------------
Test::Test(Type type)
{
switch (type) {
case Qt4Client: {
qDebug("qt4client");
My4Socket *s = new My4Socket(this);
s->connectToHost("localhost", 7700);
s->sendTest(1);
break;
}
case Qt4Server: {
new My4Server(this);
break;
}
default:
break;
}
}

View File

@ -0,0 +1,57 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TEST_H
#define TEST_H
//------------------------------------------------------------------------------
#include <QTcpServer>
#include <QTcpSocket>
//------------------------------------------------------------------------------
class My4Socket : public QTcpSocket
{
Q_OBJECT
public:
My4Socket(QObject *parent);
void sendTest(quint32 num);
bool safeShutDown;
private slots:
void read();
void closed();
};
//------------------------------------------------------------------------------
class My4Server : public QTcpServer
{
Q_OBJECT
public:
My4Server(QObject *parent = nullptr);
protected:
void incomingConnection(qintptr socket) override;
private slots:
void stopServer();
private:
My4Socket *m_socket;
};
//------------------------------------------------------------------------------
class Test : public QObject
{
Q_OBJECT
public:
enum Type {
Qt4Client,
Qt4Server,
};
Test(Type type);
};
//------------------------------------------------------------------------------
#endif // TEST_H

View File

@ -0,0 +1,29 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "Test.h"
#include <QCoreApplication>
#include <QStringList>
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
QString arg;
if (app.arguments().size() > 1)
arg = app.arguments().at(1).toLower().trimmed();
Test::Type type;
if (arg == QLatin1String("qt4client"))
type = Test::Qt4Client;
else if (arg == QLatin1String("qt4server"))
type = Test::Qt4Server;
else {
qDebug("usage: ./stressTest <qt4client|qt4server>");
return 0;
}
Test test(type);
return app.exec();
}

View File

@ -0,0 +1,24 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qtcpsocket Test:
#####################################################################
qt_internal_add_test(tst_qtcpsocket
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../"
SOURCES
../tst_qtcpsocket.cpp
LIBRARIES
Qt::CorePrivate
Qt::NetworkPrivate
QT_TEST_SERVER_LIST "danted" "squid" "apache2" "ftp-proxy" "vsftpd" "iptables" "cyrus"
)
## Scopes:
#####################################################################
qt_internal_extend_target(tst_qtcpsocket CONDITION WIN32
LIBRARIES
ws2_32
)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,13 @@
[writeDatagramToNonExistingPeer]
windows
# QTBUG-85364
windows-10 gcc cmake
[readyReadForEmptyDatagram]
opensuse-leap
[echo]
opensuse-42.3
[multicast]
centos
macos arm
[linkLocalIPv6]
macos arm

View File

@ -0,0 +1,5 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
add_subdirectory(test)
add_subdirectory(clientserver)

View File

@ -0,0 +1,14 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## clientserver Binary:
#####################################################################
qt_internal_add_executable(clientserver
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
SOURCES
main.cpp
LIBRARIES
Qt::Network
)

View File

@ -0,0 +1,136 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtNetwork>
class ClientServer : public QUdpSocket
{
Q_OBJECT
public:
enum Type {
ConnectedClient,
UnconnectedClient,
Server
};
ClientServer(Type type, const QString &host, quint16 port)
: type(type)
{
switch (type) {
case Server:
if (bind(0, ShareAddress | ReuseAddressHint)) {
printf("%d\n", localPort());
} else {
printf("XXX\n");
}
break;
case ConnectedClient:
connectToHost(host, port);
startTimer(250);
printf("ok\n");
break;
case UnconnectedClient:
peerAddress = QHostAddress(host);
peerPort = port;
if (bind(QHostAddress::Any, port + 1, ShareAddress | ReuseAddressHint)) {
startTimer(250);
printf("ok\n");
} else {
printf("XXX\n");
}
break;
}
fflush(stdout);
connect(this, SIGNAL(readyRead()), this, SLOT(readTestData()));
}
protected:
void timerEvent(QTimerEvent *event) override
{
static int n = 0;
switch (type) {
case ConnectedClient:
write(QByteArray::number(n++));
break;
case UnconnectedClient:
writeDatagram(QByteArray::number(n++), peerAddress, peerPort);
break;
default:
break;
}
QUdpSocket::timerEvent(event);
}
private slots:
void readTestData()
{
printf("readData()\n");
switch (type) {
case ConnectedClient: {
while (bytesAvailable() || hasPendingDatagrams()) {
QByteArray data = readAll();
printf("got %d\n", data.toInt());
}
break;
}
case UnconnectedClient: {
while (hasPendingDatagrams()) {
QByteArray data;
data.resize(pendingDatagramSize());
readDatagram(data.data(), data.size());
printf("got %d\n", data.toInt());
}
break;
}
case Server: {
while (hasPendingDatagrams()) {
QHostAddress sender;
quint16 senderPort;
QByteArray data;
data.resize(pendingDatagramSize());
readDatagram(data.data(), data.size(), &sender, &senderPort);
printf("got %d\n", data.toInt());
printf("sending %d\n", data.toInt() * 2);
writeDatagram(QByteArray::number(data.toInt() * 2), sender, senderPort);
}
break;
}
}
fflush(stdout);
}
private:
Type type;
QHostAddress peerAddress;
quint16 peerPort;
};
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
ClientServer::Type type;
if (app.arguments().size() < 4) {
qDebug("usage: %s [ConnectedClient <server> <port>|UnconnectedClient <server> <port>|Server]", argv[0]);
return 1;
}
QString arg = app.arguments().at(1).trimmed().toLower();
if (arg == "connectedclient") {
type = ClientServer::ConnectedClient;
} else if (arg == "unconnectedclient") {
type = ClientServer::UnconnectedClient;
} else if (arg == "server") {
type = ClientServer::Server;
} else {
qDebug("usage: %s [ConnectedClient <server> <port>|UnconnectedClient <server> <port>|Server]", argv[0]);
return 1;
}
ClientServer clientServer(type, app.arguments().at(2),
app.arguments().at(3).toInt());
return app.exec();
}
#include "main.moc"

View File

@ -0,0 +1,16 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qudpsocket Test:
#####################################################################
qt_internal_add_test(tst_qudpsocket
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../"
SOURCES
../tst_qudpsocket.cpp
LIBRARIES
Qt::Network
Qt::TestPrivate
QT_TEST_SERVER_LIST "danted" "echo"
)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,14 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## udpServer Binary:
#####################################################################
qt_internal_add_executable(udpServer
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/./"
SOURCES
main.cpp
LIBRARIES
Qt::Network
)

View File

@ -0,0 +1,66 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtNetwork>
class Server : public QObject
{
Q_OBJECT
public:
Server() { connect(&serverSocket, &QIODevice::readyRead, this, &Server::sendEcho); }
bool bind(quint16 port)
{
const bool result = serverSocket.bind(QHostAddress::Any, port,
QUdpSocket::ReuseAddressHint
| QUdpSocket::ShareAddress);
if (result) {
printf("OK\n");
} else {
printf("FAILED: %s\n", qPrintable(serverSocket.errorString()));
}
fflush(stdout);
return result;
}
private slots:
void sendEcho()
{
QHostAddress senderAddress;
quint16 senderPort;
char data[1024];
qint64 bytes = serverSocket.readDatagram(data, sizeof(data), &senderAddress, &senderPort);
if (bytes == 1 && data[0] == '\0')
QCoreApplication::instance()->quit();
for (int i = 0; i < bytes; ++i)
data[i] += 1;
serverSocket.writeDatagram(data, bytes, senderAddress, senderPort);
}
private:
QUdpSocket serverSocket;
};
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
QStringList arguments = QCoreApplication::arguments();
arguments.pop_front();
quint16 port = 0;
if (!arguments.isEmpty())
port = arguments.constFirst().toUShort();
if (!port) {
printf("Specify port number\n");
return -1;
}
Server server;
if (!server.bind(port))
return -2;
return app.exec();
}
#include "main.moc"