1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| //.h
//-------------------------------------------
class MyTask : public QObject, public QRunnable
{
public:
MyTask(const QHostAddress &address, int port, const QByteArray &data, QObject *parent = 0);
private:
const QByteArray m_data;
const QHostAddress m_address;
const int m_port;
int m_timeout;
bool m_connected;
signals:
void error(const QString &error);
void result(bool ok);
private slots:
void onTcpError(QAbstractSocket::SocketError e);
void onConnected();
}
//.cpp
//-------------------------------------------
MyTask::MyTask(const QHostAddress &address, int port, const QByteArray &data, QObject *parent)
: QObject(parent), m_address(address), m_port(port), m_data(data), m_timeout(5000)
{
}
void MyTask::run()
{
QTcpSocket socket;
QByteArray data;
QByteArray response;
bool ok = false;
//CONNECT
connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(onTcpError(QAbstractSocket::SocketError)), Qt::DirectConnection);
connect(&socket, SIGNAL(connected()), this, SLOT(onConnected()), Qt::DirectConnection);
socket.connectToHost(m_address, m_port());
//WAIT CONNECTED
QElapsedTimer t;
t.start();
//Wait socket is connected using connected() signal.
//on Windows, waitForConnected() does not seem to work
//So it a good occasion to provide "smooth" progress monitoring
while(!m_connected && (t.elapsed() < m_timeout)){
QGuiApplication::processEvents(QEventLoop::AllEvents, 10);
}
if(m_connected){
//Write
socket.write(data);
//Attente de la réponse, si nécessaire.
t.restart();
while(socket.waitForReadyRead(m_timeout) || !ok){
response.append(socket.readAll());
ok = response.size() > 1; //taille minimum de la réponse
}
} else {
emit error(socket.errorString());
}
if(!ok){
emit error("Timeout occur when waiting for response");
}
emit result(ok);
if(socket.state() == QAbstractSocket::ConnectedState){
socket.disconnectFromHost();
socket.waitForDisconnected();
}
}
void MyTask::onTcpError(QAbstractSocket::SocketError e)
{
Q_UNUSED(e)
QTcpSocket *s = qobject_cast<QTcpSocket *>(sender());
if(s)
emit error(s->errorString());
}
void MyTask::onConnected()
{
m_connected = true;
}
//Utilisation
MyTask *task = new MyTask(address, port, data);
task->setAutoDelete(true);
connect(task, SIGNAL(error(QString)), this, SIGNAL(onSendDataError(QString)));
connect(task, SIGNAL(result(bool)), this, SLOT(onSendDataResult(bool)));
QThreadPoool::globalInstance()->start(task); |
Partager