mirror of
https://github.com/crystalidea/qt6windows7.git
synced 2024-12-02 08:33:00 +08:00
102 lines
3.3 KiB
Plaintext
102 lines
3.3 KiB
Plaintext
// 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
|
|
\examplecategory {Networking}
|
|
\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
|
|
*/
|
|
|