The code below shows how to create a socket that can operate over an Transport Layer Security (TLS, also known as SSL) connection.
#ifndef TLSSOCKET_H
#include <QTcpSocket>
#include <QtCrypto>
class TLSSocket : public QTcpSocket
{
Q_OBJECT
public:
TLSSocket(
QObject *parent =
nullptr);
~TLSSocket() override;
void connectToHostEncrypted(const QString &host, quint16 port);
bool waitForReadyRead(int msecs = -1) override;
protected:
qint64 readData(char *data, qint64 maxlen) override;
qint64 writeData(const char *data, qint64 len) override;
private:
class Private;
friend class Private;
Private *d;
};
#endif
#include "tlssocket.h"
#include <QCoreApplication>
int main(int argc, char **argv)
{
QCoreApplication qapp(argc, argv);
TLSSocket socket;
socket.connectToHostEncrypted(QStringLiteral("www.paypal.com"), 443);
socket.write("GET / HTTP/1.0\r\n\r\n");
while (socket.waitForReadyRead())
printf("%s", socket.readAll().constData());
return 0;
}
#include "tlssocket.h"
#ifdef QT_STATICPLUGIN
#include "import_plugins.h"
#endif
class TLSSocket::Private :
public QObject {
Q_OBJECT
public:
TLSSocket * q;
QTcpSocket * sock;
QString host;
bool encrypted;
bool error, done;
QByteArray readbuf, writebuf;
bool waiting;
Private(TLSSocket *_q)
, q(_q)
, sync(_q)
{
sock = new QTcpSocket(this);
connect(sock, &QTcpSocket::connected, this, &TLSSocket::Private::sock_connected);
connect(sock, &QTcpSocket::readyRead, this, &TLSSocket::Private::sock_readyRead);
connect(sock, &QTcpSocket::bytesWritten, this, &TLSSocket::Private::sock_bytesWritten);
connect(sock,
QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error),
this,
&TLSSocket::Private::sock_error);
encrypted = false;
error = false;
waiting = false;
done = false;
}
bool waitForReadyRead(int msecs)
{
waiting = true;
waiting = false;
if (error || done)
return false;
return ok;
}
private Q_SLOTS:
void sock_connected()
{
}
void sock_readyRead()
{
QByteArray buf = sock->readAll();
}
void sock_bytesWritten(qint64 x)
{
Q_UNUSED(x);
}
void sock_error(QAbstractSocket::SocketError x)
{
Q_UNUSED(x);
done = true;
if (waiting)
}
void tls_handshaken()
{
printf("not valid\n");
sock->abort();
error = true;
} else {
encrypted = true;
if (!writebuf.isEmpty()) {
writebuf.clear();
}
}
if (waiting)
}
void tls_readyRead()
{
if (waiting)
}
void tls_readyReadOutgoing()
{
sock->write(buf);
}
void tls_closed()
{
}
void tls_error()
{
}
};
TLSSocket::TLSSocket(
QObject *parent)
: QTcpSocket(parent)
{
d = new Private(this);
}
TLSSocket::~TLSSocket()
{
delete d;
}
void TLSSocket::connectToHostEncrypted(const QString &host, quint16 port)
{
d->host = host;
setOpenMode(QIODevice::ReadWrite);
d->sock->connectToHost(host, port);
}
{
return d->tls;
}
bool TLSSocket::waitForReadyRead(int msecs)
{
return d->waitForReadyRead(msecs);
}
qint64 TLSSocket::readData(char *data, qint64 maxlen)
{
if (!d->error)
d->readbuf += d->tls->
read();
unsigned char *p = (unsigned char *)d->readbuf.data();
int size = d->readbuf.size();
int readsize = qMin(size, (int)maxlen);
int newsize = size - readsize;
memcpy(data, p, readsize);
memmove(p, p + readsize, newsize);
d->readbuf.resize(newsize);
return readsize;
}
qint64 TLSSocket::writeData(const char *data, qint64 len)
{
QByteArray buf(data, len);
if (d->encrypted)
d->tls->write(buf);
else
d->writebuf += buf;
return len;
}
#include "tlssocket.moc"