Гоняю данные по сети с помощью QSslSocket.
Непонятно как правильно обрабатывать обрывы и ошибки «правильно».
Чтобы упростить набросал пример в котором шлем запрос на вэбсервер и читаем пстрочно ответ:
#include "cnetworking.h"
CNetworking::CNetworking(QString host, quint16 port):
b_sock_disconnected(false),
b_sock_error_occured(false)
{
ssl_sock = new QSslSocket();
connect(ssl_sock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(SockErrorSlot()));
connect(ssl_sock, SIGNAL(disconnected()), this, SLOT(SockDisconnectedSlot()));
ssl_sock->connectToHostEncrypted(host, port);
//Сразу ждем зашифрованного соединения
if(!ssl_sock->waitForEncrypted() ) {
SetErrors();
return;
}
//Шлем какие-то данные
ssl_sock->write("GET / HTTP/1.1\r\nHost: yandex.ru\r\n\r\n");
//Читаем построчно до признака окончания
QByteArray ba;
bool flag = true;
do {
//Если что-то с соединеием не так...
if(!isConnectionOk()) {
SetErrors();
return;
}
if(ssl_sock->waitForReadyRead()) {
if(ssl_sock->canReadLine()) {
ba = ssl_sock->readLine();//В реальности тут что-то делаем с данными
if(ba == "\r\n")
flag = false;
}
}
}while(flag);
}
//Все ли нормально с соединением
bool CNetworking::isConnectionOk() {
if(b_sock_disconnected == true || b_sock_error_occured == true)
return false;
return true;
}
void CNetworking::SetErrors() {
sock_error = ssl_sock->error();
sock_error_str = ssl_sock->errorString();
}
QString CNetworking::GetErrorStr() {
return sock_error_str;
}
int CNetworking::GetError() {
return sock_error;
}
void CNetworking::SockDisconnectedSlot() {
qDebug() << "SockDisconnectedSlot";
b_sock_disconnected = true;
}
void CNetworking::SockErrorSlot(QAbstractSocket::SocketError) {
b_sock_error_occured = true;
qDebug() << "SockErrorSlot";
SetErrors();
}
CNetworking::~CNetworking() {
}
-----------------------------------
#ifndef CNetworking_H
#define CNetworking_H
#include <QSslSocket>
#include <QString>
class CNetworking: public QObject
{
Q_OBJECT
public:
CNetworking(QString host, quint16 port/*, quint16 data_read_timeout_msec*/);
int GetError();
QString GetErrorStr();
virtual ~CNetworking();
private:
bool isConnectionOk();
void SetErrors();
QSslSocket* ssl_sock;
bool b_sock_disconnected;
bool b_sock_error_occured;
QString sock_error_str;
QAbstractSocket::SocketError sock_error;
private slots:
void SockDisconnectedSlot();
void SockErrorSlot(QAbstractSocket::SocketError);
};
#endif // CNetworking_H
У меня есть сомнения:
Кажется странным везде перед чтением/записью лепить
проверку
//Если что-то с соединеием не так...
if(!isConnectionOk()) {
SetErrors();
return;
}
И другой момент касается использования waitForReadyRead(). В документации сказано
Reimplemented from QAbstractSocket::waitForReadyRead().
Note: This function may fail randomly on Windows. Consider using the event loop and the readyRead() signal if your software will run on Windows.
QEventLoop myloop;
myloop.connect(ssl_sock, SIGNAL(connected()), SLOT(quit()));
myloop.connect(ssl_sock, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(quit()));
myloop.exec();
Благодарю за любую помощь, критику или подсказки