#include "tcpsocket.h" TcpSocket::TcpSocket(QObject *parent) : QTcpSocket{parent} { connect(this, &QTcpSocket::errorOccurred, this, [this]() { { std::lock_guard lock(mtx); hasErr = true; } cv.notify_all(); }); connect(this, &QTcpSocket::connected, this, [this]() { { std::lock_guard lock(mtx); } cv.notify_all(); }); connect(this, &QTcpSocket::disconnected, this, [this]() { { std::lock_guard lock(mtx); } cv.notify_all(); }); connect(this, &QTcpSocket::bytesWritten, this, [this]() { { std::lock_guard lock(mtx); isWritten = true; } cv.notify_all(); }); connect(this, &QTcpSocket::readyRead, this, [this]() { { std::lock_guard lock(mtx); isReadyRead = true; } cv.notify_all(); }); } bool TcpSocket::waitForConnected(int msecs) { if(hasErr) return false; if(state() == ConnectedState) return true; { std::unique_lock lock(mtx); if(hasErr) return false; if(state() == ConnectedState) return true; auto until = std::chrono::steady_clock::now() + std::chrono::milliseconds(msecs); auto check = until - std::chrono::milliseconds(10); do { cv.wait_until(lock, until); if(hasErr) return false; if(state() == ConnectedState) return true; } while(std::chrono::steady_clock::now() < check); } hasErr = true; setSocketError(SocketTimeoutError); return false; } bool TcpSocket::waitForDisconnected(int msecs) { if(hasErr) return false; if(state() == UnconnectedState) return true; { std::unique_lock lock(mtx); if(hasErr) return false; if(state() == UnconnectedState) return true; auto until = std::chrono::steady_clock::now() + std::chrono::milliseconds(msecs); auto check = until - std::chrono::milliseconds(10); do { cv.wait_until(lock, until); if(hasErr) return false; if(state() == UnconnectedState) return true; } while(std::chrono::steady_clock::now() < check); } hasErr = true; setSocketError(SocketTimeoutError); return false; } bool TcpSocket::waitForBytesWritten(int msecs) { if(hasErr) return false; if(isWritten) return true; { std::unique_lock lock(mtx); if(hasErr) return false; if(isWritten) return true; auto until = std::chrono::steady_clock::now() + std::chrono::milliseconds(msecs); auto check = until - std::chrono::milliseconds(10); do { cv.wait_until(lock, until); if(hasErr) return false; if(isWritten) return true; } while(std::chrono::steady_clock::now() < check); } hasErr = true; setSocketError(SocketTimeoutError); return false; } bool TcpSocket::waitForReadyRead(int msecs) { if(hasErr) return false; if(isReadyRead) return true; { std::unique_lock lock(mtx); if(hasErr) return false; if(isReadyRead) return true; auto until = std::chrono::steady_clock::now() + std::chrono::milliseconds(msecs); auto check = until - std::chrono::milliseconds(10); do { cv.wait_until(lock, until); if(hasErr) return false; if(isReadyRead) return true; } while(std::chrono::steady_clock::now() < check); } hasErr = true; setSocketError(SocketTimeoutError); return false; } qint64 TcpSocket::readData(char *data, qint64 maxlen) { auto rtn = QTcpSocket::readData(data, maxlen); isReadyRead = false; return rtn; } qint64 TcpSocket::readLineData(char *data, qint64 maxlen) { auto rtn = QTcpSocket::readLineData(data, maxlen); isReadyRead = false; return rtn; } qint64 TcpSocket::writeData(const char *data, qint64 len) { isWritten = false; return QTcpSocket::writeData(data, len); }