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

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,175 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example blockingfortuneclient
\title Blocking Fortune Client
\examplecategory {Networking}
\meta tags {tcp,network,threading,synchronous-io}
\ingroup examples-network
\brief Demonstrates how to create a client for a network service.
\image blockingfortuneclient-example.png
QTcpSocket supports two general approaches to network programming:
\list
\li \e{The asynchronous (non-blocking) approach.} Operations are scheduled
and performed when control returns to Qt's event loop. When the operation
is finished, QTcpSocket emits a signal. For example,
QTcpSocket::connectToHost() returns immediately, and when the connection
has been established, QTcpSocket emits
\l{QTcpSocket::connected()}{connected()}.
\li \e{The synchronous (blocking) approach.} In non-GUI and multithreaded
applications, you can call the \c waitFor...() functions (e.g.,
QTcpSocket::waitForConnected()) to suspend the calling thread until the
operation has completed, instead of connecting to signals.
\endlist
The implementation is very similar to the
\l{fortuneclient}{Fortune Client} example, but instead of having
QTcpSocket as a member of the main class, doing asynchronous networking in
the main thread, we will do all network operations in a separate thread
and use QTcpSocket's blocking API.
The purpose of this example is to demonstrate a pattern that you can use
to simplify your networking code, without losing responsiveness in your
user interface. Use of Qt's blocking network API often leads to
simpler code, but because of its blocking behavior, it should only be used
in non-GUI threads to prevent the user interface from freezing. But
contrary to what many think, using threads with QThread does not
necessarily add unmanagable complexity to your application.
We will start with the FortuneThread class, which handles the network
code.
\snippet blockingfortuneclient/fortunethread.h 0
FortuneThread is a QThread subclass that provides an API for scheduling
requests for fortunes, and it has signals for delivering fortunes and
reporting errors. You can call requestNewFortune() to request a new
fortune, and the result is delivered by the newFortune() signal. If any
error occurs, the error() signal is emitted.
It's important to notice that requestNewFortune() is called from the main,
GUI thread, but the host name and port values it stores will be accessed
from FortuneThread's thread. Because we will be reading and writing
FortuneThread's data members from different threads concurrently, we use
QMutex to synchronize access.
\snippet blockingfortuneclient/fortunethread.cpp 2
The requestNewFortune() function stores the host name and port of the
fortune server as member data, and we lock the mutex with QMutexLocker to
protect this data. We then start the thread, unless it is already
running. We will come back to the QWaitCondition::wakeOne() call later.
\snippet blockingfortuneclient/fortunethread.cpp 4
\snippet blockingfortuneclient/fortunethread.cpp 5
In the run() function, we start by acquiring the mutex lock, fetching the
host name and port from the member data, and then releasing the lock
again. The case that we are protecting ourselves against is that \c
requestNewFortune() could be called at the same time as we are fetching
this data. QString is \l reentrant but \e not \l{thread-safe}, and we must
also avoid the unlikely risk of reading the host name from one request,
and port of another. And as you might have guessed, FortuneThread can only
handle one request at a time.
The run() function now enters a loop:
\snippet blockingfortuneclient/fortunethread.cpp 6
The loop will continue requesting fortunes for as long as \e quit is
false. We start our first request by creating a QTcpSocket on the stack,
and then we call \l{QTcpSocket::connectToHost()}{connectToHost()}. This
starts an asynchronous operation which, after control returns to Qt's
event loop, will cause QTcpSocket to emit
\l{QTcpSocket::connected()}{connected()} or
\l{QTcpSocket::error()}{error()}.
\snippet blockingfortuneclient/fortunethread.cpp 8
But since we are running in a non-GUI thread, we do not have to worry
about blocking the user interface. So instead of entering an event loop,
we simply call QTcpSocket::waitForConnected(). This function will wait,
blocking the calling thread, until QTcpSocket emits connected() or an
error occurs. If connected() is emitted, the function returns true; if the
connection failed or timed out (which in this example happens after 5
seconds), false is returned. QTcpSocket::waitForConnected(), like the
other \c waitFor...() functions, is part of QTcpSocket's \e{blocking
API}.
After this statement, we have a connected socket to work with.
\snippet blockingfortuneclient/fortunethread.cpp 11
Now we can create a QDataStream object, passing the socket to
QDataStream's constructor, and as in the other client examples we set
the stream protocol version to QDataStream::Qt_4_0.
\snippet blockingfortuneclient/fortunethread.cpp 12
We proceed by initiating a loop that waits for the fortune string data by
calling QTcpSocket::waitForReadyRead(). If it returns false, we abort the
operation. After this statement, we start a stream read transaction. We
exit the loop when QDataStream::commitTransaction() returns true, which
means successful fortune string loading. The resulting fortune is
delivered by emitting newFortune():
\snippet blockingfortuneclient/fortunethread.cpp 15
The final part of our loop is that we acquire the mutex so that we can
safely read from our member data. We then let the thread go to sleep by
calling QWaitCondition::wait(). At this point, we can go back to
requestNewFortune() and look closely at the call to wakeOne():
\snippet blockingfortuneclient/fortunethread.cpp 1
\dots
\snippet blockingfortuneclient/fortunethread.cpp 3
What happened here was that because the thread falls asleep waiting for a
new request, we needed to wake it up again when a new request
arrives. QWaitCondition is often used in threads to signal a wakeup call
like this.
\snippet blockingfortuneclient/fortunethread.cpp 0
Finishing off the FortuneThread walkthrough, this is the destructor that
sets \e quit to true, wakes up the thread and waits for the thread to exit
before returning. This lets the \c while loop in run() will finish its current
iteration. When run() returns, the thread will terminate and be destroyed.
Now for the BlockingClient class:
\snippet blockingfortuneclient/blockingclient.h 0
BlockingClient is very similar to the Client class in the
\l{fortuneclient}{Fortune Client} example, but in this class
we store a FortuneThread member instead of a pointer to a QTcpSocket.
When the user clicks the "Get Fortune" button, the same slot is called,
but its implementation is slightly different:
\snippet blockingfortuneclient/blockingclient.cpp 0
We connect our FortuneThread's two signals newFortune() and error() (which
are somewhat similar to QTcpSocket::readyRead() and QTcpSocket::error() in
the previous example) to requestNewFortune() and displayError().
\snippet blockingfortuneclient/blockingclient.cpp 1
The requestNewFortune() slot calls FortuneThread::requestNewFortune(),
which \e schedules the request. When the thread has received a new fortune
and emits newFortune(), our showFortune() slot is called:
\snippet blockingfortuneclient/blockingclient.cpp 2
\codeline
\snippet blockingfortuneclient/blockingclient.cpp 3
Here, we simply display the fortune we received as the argument.
\sa {Fortune Client}, {Fortune Server}
*/

View File

@ -0,0 +1,14 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example broadcastreceiver
\title Broadcast Receiver Example
\ingroup examples-network
\brief Demonstrates how to receive information broadcasted over a local network.
This example uses the Qt Network APIs to demonstrate how to receive
messages broadcasted over a local network.
\image broadcastreceiver-example.png
*/

View File

@ -0,0 +1,14 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example broadcastsender
\title Broadcast Sender Example
\ingroup examples-network
\brief Demonstrates how to broadcast information to multiple clients on a local network.
This example uses Qt Network APIs to demonstrate how to broadcast messages
to multiple clients over a local network.
\image broadcastsender-example.png
*/

View File

@ -0,0 +1,138 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example fortuneclient
\title Fortune Client
\examplecategory {Networking}
\meta tags {tcp,network}
\ingroup examples-network
\brief Demonstrates how to create a client for a network service.
This example uses QTcpSocket, and is intended to be run alongside the
\l{fortuneserver}{Fortune Server} example or
the \l{threadedfortuneserver}{Threaded Fortune Server} example.
\image fortuneclient-example.png Screenshot of the Fortune Client example
This example uses a simple QDataStream-based data transfer protocol to
request a line of text from a fortune server (from the
\l{fortuneserver}{Fortune Server} example). The client requests a
fortune by simply connecting to the server. The server then responds with
a QString which contains the fortune text.
QTcpSocket supports two general approaches to network programming:
\list
\li \e{The asynchronous (non-blocking) approach.} Operations are scheduled
and performed when control returns to Qt's event loop. When the operation
is finished, QTcpSocket emits a signal. For example,
QTcpSocket::connectToHost() returns immediately, and when the connection
has been established, QTcpSocket emits
\l{QTcpSocket::connected()}{connected()}.
\li \e{The synchronous (blocking) approach.} In non-GUI and multithreaded
applications, you can call the \c waitFor...() functions (e.g.,
QTcpSocket::waitForConnected()) to suspend the calling thread until the
operation has completed, instead of connecting to signals.
\endlist
In this example, we will demonstrate the asynchronous approach. The
\l{blockingfortuneclient}{Blocking Fortune Client} example
illustrates the synchronous approach.
Our class contains some data and a few private slots:
\snippet fortuneclient/client.h 0
Other than the widgets that make up the GUI, the data members include a
QTcpSocket pointer, a QDataStream object that operates on the socket, and
a copy of the fortune text currently displayed.
The socket is initialized in the Client constructor. We'll pass the main
widget as parent, so that we won't have to worry about deleting the
socket:
\snippet fortuneclient/client.cpp 0
\dots
\snippet fortuneclient/client.cpp 1
The protocol is based on QDataStream, so we set the stream device to the
newly created socket. We then explicitly set the protocol version of the
stream to QDataStream::Qt_4_0 to ensure that we're using the same version
as the fortune server, no matter which version of Qt the client and
server use.
The only QTcpSocket signals we need in this example are
QTcpSocket::readyRead(), signifying that data has been received, and
QTcpSocket::errorOccurred(), which we will use to catch any connection errors:
\dots
\snippet fortuneclient/client.cpp 3
\dots
\snippet fortuneclient/client.cpp 5
Clicking the \uicontrol{Get Fortune} button will invoke the \c
requestNewFortune() slot:
\snippet fortuneclient/client.cpp 6
Because we allow the user to click \uicontrol{Get Fortune} before the
previous connection finished closing, we start off by aborting the
previous connection by calling QTcpSocket::abort(). (On an unconnected
socket, this function does nothing.) We then proceed to connecting to the
fortune server by calling QTcpSocket::connectToHost(), passing the
hostname and port from the user interface as arguments.
As a result of calling \l{QTcpSocket::connectToHost()}{connectToHost()},
one of two things can happen:
\list
\li \e{The connection is established.} In this case, the server will send us a
fortune. QTcpSocket will emit \l{QTcpSocket::readyRead()}{readyRead()}
every time it receives a block of data.
\li \e{An error occurs.} We need to inform the user if the connection
failed or was broken. In this case, QTcpSocket will emit
\l{QTcpSocket::errorOccurred()}{errorOccurred()}, and \c Client::displayError() will be
called.
\endlist
Let's go through the \l{QTcpSocket::errorOccurred()}{errorOccurred()} case first:
\snippet fortuneclient/client.cpp 13
We pop up all errors in a dialog using
QMessageBox::information(). QTcpSocket::RemoteHostClosedError is silently
ignored, because the fortune server protocol ends with the server closing
the connection.
Now for the \l{QTcpSocket::readyRead()}{readyRead()} alternative. This
signal is connected to \c Client::readFortune():
\snippet fortuneclient/client.cpp 8
Now, TCP is based on sending a stream of data, so we cannot expect to get
the entire fortune in one go. Especially on a slow network, the data can
be received in several small fragments. QTcpSocket buffers up all incoming
data and emits \l{QTcpSocket::readyRead()}{readyRead()} for every new
block that arrives, and it is our job to ensure that we have received all
the data we need before we start parsing.
For this purpose we use a QDataStream read transaction. It keeps reading
stream data into an internal buffer and rolls it back in case of an
incomplete read. We start by calling startTransaction() which also resets
the stream status to indicate that new data was received on the socket.
We proceed by using QDataStream's streaming operator to read the fortune
from the socket into a QString. Once read, we complete the transaction by
calling QDataStream::commitTransaction(). If we did not receive a full
packet, this function restores the stream data to the initial position,
after which we can wait for a new readyRead() signal.
After a successful read transaction, we call QLabel::setText() to display
the fortune.
\sa {Fortune Server}, {Blocking Fortune Client}
*/

View File

@ -0,0 +1,75 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example fortuneserver
\title Fortune Server
\examplecategory {Networking}
\meta tags {tcp,network,server}
\ingroup examples-network
\brief Demonstrates how to create a server for a network service.
This example is intended to be run alongside the
\l{fortuneclient}{Fortune Client} example or the
\l{blockingfortuneclient}{Blocking Fortune Client} example.
\image fortuneserver-example.png Screenshot of the Fortune Server example
It uses QTcpServer to accept incoming TCP connections, and a
simple QDataStream based data transfer protocol to write a fortune to the
connecting client (from the \l{fortuneclient}{Fortune Client}
example), before closing the connection.
\snippet fortuneserver/server.h 0
The server is implemented using a simple class with only one slot, for
handling incoming connections.
\snippet fortuneserver/server.cpp 1
In its constructor, our Server object calls QTcpServer::listen() to set up
a QTcpServer to listen on all addresses, on an arbitrary port. In then
displays the port QTcpServer picked in a label, so that user knows which
port the fortune client should connect to.
\snippet fortuneserver/server.cpp 2
Our server generates a list of random fortunes that it can send to
connecting clients.
\snippet fortuneserver/server.cpp 3
When a client connects to our server, QTcpServer will emit
QTcpServer::newConnection(). In turn, this will invoke our
sendFortune() slot:
\snippet fortuneserver/server.cpp 4
The purpose of this slot is to select a random line from our list of
fortunes, encode it into a QByteArray using QDataStream, and then write it
to the connecting socket. This is a common way to transfer binary data
using QTcpSocket. First we create a QByteArray and a QDataStream object,
passing the bytearray to QDataStream's constructor. We then explicitly set
the protocol version of QDataStream to QDataStream::Qt_5_10 to ensure that
we can communicate with clients from future versions of Qt (see
QDataStream::setVersion()). We continue by streaming in a random fortune.
\snippet fortuneserver/server.cpp 7
We then call QTcpServer::nextPendingConnection(), which returns the
QTcpSocket representing the server side of the connection. By connecting
QTcpSocket::disconnected() to QObject::deleteLater(), we ensure that the
socket will be deleted after disconnecting.
\snippet fortuneserver/server.cpp 8
The encoded fortune is written using QTcpSocket::write(), and we finally
call QTcpSocket::disconnectFromHost(), which will close the connection
after QTcpSocket has finished writing the fortune to the network. Because
QTcpSocket works asynchronously, the data will be written after this
function returns, and control goes back to Qt's event loop. The socket
will then close, which in turn will cause QObject::deleteLater() to delete
it.
\sa {Fortune Client}, {Threaded Fortune Server}
*/

View File

@ -0,0 +1,81 @@
// Copyright (C) 2020 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example http
\examplecategory {Networking}
\meta tags {http,network,https,proxy}
\title HTTP Client
\ingroup examples-network
\brief Demonstrates a simple HTTP client.
This example demonstrates how a simple HTTP client can fetch files
from remote hosts.
\image http-example.webp
The main work of this example is done in the HttpWindow class.
Thus we will focus on that.
\snippet http/httpwindow.cpp qnam-download
Using QNetworkAccessManager, we begin the download of a resource as
pointed to by the \c url. If you are unfamiliar with it or the function used,
QNetworkAccessManager::get(), or simply want to look into it in more detail,
take a look at its documentation and the documentation for
QNetworkReply and QNetworkRequest.
\snippet http/httpwindow.cpp connecting-reply-to-slots
Above, we connect some of the reply's signals to slots in the class.
These slots will take care of both incoming data and finalizing the
download/handling errors.
\snippet http/httpwindow.cpp networkreply-readyread-1
As for handling the incoming data, since we don't know the maximum
download size of any potential input and we don't want to exhaust
the memory of any computer which might run the example program, we
handle incoming data in QNetworkReply::readyRead() instead of in
QNetworkReply::finished().
\snippet http/httpwindow.cpp networkreply-readyread-2
Then we write the data to file as it arrives. It is less convenient,
but the application will consume less memory at its peak!
\snippet http/httpwindow.cpp sslerrors-1
With the QNetworkReply::sslErrors() signal we can also handle errors that may
occur during the TLS handshake when connecting to secure websites (i.e. HTTPS).
\snippet http/httpwindow.cpp sslerrors-2
In this example, we show a dialog to the user so that they can choose whether
or not to ignore the errors.
\snippet http/httpwindow.cpp networkreply-error-handling-1
\snippet http/httpwindow.cpp networkreply-error-handling-2
If an error occurs then QNetworkReply will emit the
QNetworkReply::errorOccurred() signal, followed by the
QNetworkReply::finished() signal. In this example, we only connect to the
latter. We handle any potential error(s) in the respective slot by deleting
the file we were writing to, and display the error with our status label.
\snippet http/httpwindow.cpp qnam-auth-required-1
If you connect to a website that uses
\l{https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication}{HTTP authentication},
assuming you didn't supply the credentials that should be used ahead of time,
you can handle missing credentials when the website requests it. With QNetworkAccessManager,
we do this in a slot connected to the signal
QNetworkAccessManager::authenticationRequired(). We make this connection once,
in the constructor.
\snippet http/httpwindow.cpp qnam-auth-required-2
In this example, we show a dialog where the user can either insert a
username and password, or cancel. Canceling causes the request to fail.
*/

View File

@ -0,0 +1,14 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example multicastreceiver
\title Multicast Receiver
\examplecategory {Networking}
\meta tags {network,multicast,ipv6,ipv4,udp}
\ingroup examples-network
\brief Demonstrates how to receive information sent to a multicast group.
This example demonstrates how to receive messages sent to a multicast group.
\image multicastreceiver-example.webp
*/

View File

@ -0,0 +1,16 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example multicastsender
\title Multicast Sender
\examplecategory {Networking}
\meta tags {network,multicast,ipv6,ipv4,udp}
\ingroup examples-network
\brief Demonstrates how to send messages to a multicast group.
This example demonstrates how to send messages to the clients of a
multicast group.
\image multicastsender-example.webp
*/

View File

@ -0,0 +1,14 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example network-chat
\title Network Chat Example
\ingroup examples-network
\brief Demonstrates a stateful peer-to-peer Chat client.
This example uses broadcasting with QUdpSocket and QNetworkInterface to
discover its peers.
\image network-chat-example.png
*/

View File

@ -0,0 +1,16 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example securesocketclient
\title Secure Socket Client Example
\ingroup examples-network
\brief Demonstrates how to communicate over an encrypted (SSL) connection.
This example uses QSslSocket to demonstrate how to communicate over an
encrypted connection, deal with authenticity problems, and display security
and certificate information.
\image securesocketclient.png
\image securesocketclient2.png
*/

View File

@ -0,0 +1,100 @@
// Copyright (C) 2018 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example secureudpclient
\title DTLS client
\ingroup examples-network
\brief This example demonstrates how to implement client-side DTLS connections.
\image secureudpclient-example.png Screenshot of the DTLS client example.
\note The DTLS client example is intended to be run alongside the \l{secureudpserver}{DTLS server} example.
The example DTLS client can establish several DTLS connections to one
or many DTLS servers. A client-side DTLS connection is implemented by the
DtlsAssociation class. This class uses QUdpSocket to read and write datagrams
and QDtls for encryption:
\snippet secureudpclient/association.h 0
The constructor sets the minimal TLS configuration for the new DTLS connection,
and sets the address and the port of the server:
\dots
\snippet secureudpclient/association.cpp 1
\dots
The QDtls::handshakeTimeout() signal is connected to the handleTimeout() slot
to deal with packet loss and retransmission during the handshake phase:
\dots
\snippet secureudpclient/association.cpp 2
\dots
To ensure we receive only the datagrams from the server, we connect our UDP socket to the server:
\dots
\snippet secureudpclient/association.cpp 3
\dots
The QUdpSocket::readyRead() signal is connected to the readyRead() slot:
\dots
\snippet secureudpclient/association.cpp 13
\dots
When a secure connection to a server is established, a DtlsAssociation object
will be sending short ping messages to the server, using a timer:
\snippet secureudpclient/association.cpp 4
startHandshake() starts a handshake with the server:
\snippet secureudpclient/association.cpp 5
The readyRead() slot reads a datagram sent by the server:
\snippet secureudpclient/association.cpp 6
If the handshake was already completed, this datagram is decrypted:
\snippet secureudpclient/association.cpp 7
otherwise, we try to continue the handshake:
\snippet secureudpclient/association.cpp 8
When the handshake has completed, we send our first ping message:
\snippet secureudpclient/association.cpp 9
The pskRequired() slot provides the Pre-Shared Key (PSK) needed during the handshake
phase:
\snippet secureudpclient/association.cpp 14
\note For the sake of brevity, the definition of pskRequired() is oversimplified.
The documentation for the QSslPreSharedKeyAuthenticator class explains in detail
how this slot can be properly implemented.
pingTimeout() sends an encrypted message to the server:
\snippet secureudpclient/association.cpp 10
During the handshake phase the client must handle possible timeouts, which
can happen due to packet loss. The handshakeTimeout() slot retransmits
the handshake messages:
\snippet secureudpclient/association.cpp 11
Before a client connection is destroyed, its DTLS connection must be shut down:
\snippet secureudpclient/association.cpp 12
Error messages, informational messages, and decrypted responses from servers
are displayed by the UI:
\snippet secureudpclient/mainwindow.cpp 0
*/

View File

@ -0,0 +1,107 @@
// Copyright (C) 2018 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example secureudpserver
\title DTLS server
\ingroup examples-network
\brief This examples demonstrates how to implement a simple DTLS server.
\image secureudpserver-example.png Screenshot of the DTLS server example.
\note The DTLS server example is intended to be run alongside the \l{secureudpclient}{DTLS client} example.
The server is implemented by the DtlsServer class. It uses QUdpSocket,
QDtlsClientVerifier, and QDtls to test each client's reachability, complete a handshake,
and read and write encrypted messages.
\snippet secureudpserver/server.h 0
The constructor connects the QUdpSocket::readyRead() signal to its
readyRead() slot and sets the minimal needed TLS configuration:
\snippet secureudpserver/server.cpp 1
\note The server is not using a certificate and is relying on Pre-Shared
Key (PSK) handshake.
listen() binds QUdpSocket:
\snippet secureudpserver/server.cpp 2
The readyRead() slot processes incoming datagrams:
\dots
\snippet secureudpserver/server.cpp 3
\dots
After extracting an address and a port number, the server first tests
if it's a datagram from an already known peer:
\dots
\snippet secureudpserver/server.cpp 4
\dots
If it is a new, unknown address and port, the datagram is processed as a
potential ClientHello message, sent by a DTLS client:
\dots
\snippet secureudpserver/server.cpp 5
\dots
If it's a known DTLS client, the server either decrypts the datagram:
\dots
\snippet secureudpserver/server.cpp 6
\dots
or continues a handshake with this peer:
\dots
\snippet secureudpserver/server.cpp 7
\dots
handleNewConnection() verifies it's a reachable DTLS client, or sends a
HelloVerifyRequest:
\snippet secureudpserver/server.cpp 8
\dots
If the new client was verified to be a reachable DTLS client, the server creates
and configures a new QDtls object, and starts a server-side handshake:
\dots
\snippet secureudpserver/server.cpp 9
\dots
doHandshake() progresses through the handshake phase:
\snippet secureudpserver/server.cpp 11
During the handshake phase, the QDtls::pskRequired() signal is emitted and
the pskRequired() slot provides the preshared key:
\snippet secureudpserver/server.cpp 13
\note For the sake of brevity, the definition of pskRequired() is oversimplified.
The documentation for the QSslPreSharedKeyAuthenticator class explains in detail
how this slot can be properly implemented.
After the handshake is completed for the network peer, an encrypted DTLS
connection is considered to be established and the server decrypts subsequent
datagrams, sent by the peer, by calling decryptDatagram(). The server also
sends an encrypted response to the peer:
\snippet secureudpserver/server.cpp 12
The server closes its DTLS connections by calling QDtls::shutdown():
\snippet secureudpserver/server.cpp 14
During its operation, the server reports errors, informational messages, and
decrypted datagrams, by emitting signals errorMessage(), warningMessage(),
infoMessage(), and datagramReceived(). These messages are logged by the server's
UI:
\snippet secureudpserver/mainwindow.cpp 0
*/

View File

@ -0,0 +1,85 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example threadedfortuneserver
\title Threaded Fortune Server
\examplecategory {Networking}
\meta tags {tcp,network,threading,server,synchronous-io}
\ingroup examples-network
\brief The Threaded Fortune Server example shows how to create a server for a
simple network service that uses threads to handle requests from different
clients. It is intended to be run alongside the Fortune Client example.
\image threadedfortuneserver-example.png
The implementation of this example is similar to that of the
\l{fortuneserver}{Fortune Server} example, but here we will
implement a subclass of QTcpServer that starts each connection in a
different thread.
For this we need two classes: FortuneServer, a QTcpServer subclass, and
FortuneThread, which inherits QThread.
\snippet threadedfortuneserver/fortuneserver.h 0
FortuneServer inherits QTcpServer and reimplements
QTcpServer::incomingConnection(). We also use it for storing the list of
random fortunes.
\snippet threadedfortuneserver/fortuneserver.cpp 0
We use FortuneServer's constructor to simply generate the list of
fortunes.
\snippet threadedfortuneserver/fortuneserver.cpp 1
Our implementation of QTcpServer::incomingConnection() creates a
FortuneThread object, passing the incoming socket descriptor and a random
fortune to FortuneThread's constructor. By connecting FortuneThread's
finished() signal to QObject::deleteLater(), we ensure that the thread
gets deleted once it has finished. We can then call QThread::start(),
which starts the thread.
\snippet threadedfortuneserver/fortunethread.h 0
Moving on to the FortuneThread class, this is a QThread subclass whose job
is to write the fortune to the connected socket. The class reimplements
QThread::run(), and it has a signal for reporting errors.
\snippet threadedfortuneserver/fortunethread.cpp 0
FortuneThread's constructor simply stores the socket descriptor and
fortune text, so that they are available for run() later on.
\snippet threadedfortuneserver/fortunethread.cpp 1
The first thing our run() function does is to create a QTcpSocket object
on the stack. What's worth noticing is that we are creating this object
inside the thread, which automatically associates the socket to the
thread's event loop. This ensures that Qt will not try to deliver events
to our socket from the main thread while we are accessing it from
FortuneThread::run().
\snippet threadedfortuneserver/fortunethread.cpp 2
The socket is initialized by calling QTcpSocket::setSocketDescriptor(),
passing our socket descriptor as an argument. We expect this to succeed,
but just to be sure, (although unlikely, the system may run out of
resources,) we catch the return value and report any error.
\snippet threadedfortuneserver/fortunethread.cpp 3
As with the \l{fortuneserver}{Fortune Server} example, we encode
the fortune into a QByteArray using QDataStream.
\snippet threadedfortuneserver/fortunethread.cpp 4
But unlike the previous example, we finish off by calling
QTcpSocket::waitForDisconnected(), which blocks the calling thread until
the socket has disconnected. Because we are running in a separate thread,
the GUI will remain responsive.
\sa {Fortune Server}, {Fortune Client}, {Blocking Fortune Client}
*/

View File

@ -0,0 +1,14 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example torrent
\title Torrent Example
\ingroup examples-network
\brief Demonstrates complex TCP/IP operations.
This example demonstrates some of the complex TCP/IP operations
supported by the Qt Network APIs.
\image torrent-example.png
*/