Monitoring internet connection status - qt

How can I monitor internet connection status in qt? What I mean is that I'd like to be able to change icon to active/inactive depend on internet connection being present or not.

If you are using QML, there is NetworkInfo QML element from Qt Mobility package. Also, that contains an example, how to check is WLAN connection present.

I use this code to check the internet status.
bool ConnectivityManager::isOnline()
{
bool retVal = false;
QNetworkAccessManager nam;
QNetworkRequest req(QUrl("http://www.google.com"));
QNetworkReply* reply = nam.get(req);
QEventLoop loop;
QTimer timeoutTimer;
connect(&timeoutTimer, SIGNAL(timeout()), &loop, SLOT(quit()));
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
timeoutTimer.setSingleShot(true);
timeoutTimer.start(3000);
loop.exec();
if (reply->bytesAvailable())
{
retVal = true;
}
return retVal;
}

I've had an issue using a solution similar to the Winston Rodrigues one and Flatpak. This solution was working on almost all computers I have tested but one. Internet connection was not detected for unclear reason (no error was raised). So, here is the solution that works for me in all situations, so far:
bool InternetIsOn()
{
QUrl host("1.1.1.1"); // put here URL (or IP) of your own website if you have one
qDebug() << tr("Checking internet connection: connecting to %1 ...").arg(host.toString());
QTcpSocket* sock = new QTcpSocket(this);
connect(sock, &QTcpSocket::errorOccurred, this, [](QAbstractSocket::SocketError error) {
qDebug() << "This error occured during Internet checking:" << error;
});
sock->connectToHost(host.toString(), 80);
bool connected = sock->waitForConnected(3'000);//ms
if (!connected)
{
sock->abort();
qDebug() << tr("%1 is not reachable. Not connected to the Internet").arg(host.toString());
return false;
}
sock->close();
qDebug() << tr("Connected to the Internet");
return true;
}

Related

QIODevice::read (QSerialPort) : device not open

I'm new with Qt Creator and I'm trying to read data from a light sensor communicating by I2C. I made a class PortListener that should return data received on the console once called.
PortListener::PortListener(const QString &portName)
{
this->port = new QSerialPort();
port->setPortName(portName);
port->setBaudRate(QSerialPort::Baud9600);
port->setDataBits(QSerialPort::Data8);
port->setParity(QSerialPort::NoParity);
port->setStopBits(QSerialPort::OneStop);
port->setFlowControl(QSerialPort::NoFlowControl);
port->open(QIODevice::ReadWrite);
QByteArray readData = port->readAll();
qDebug() << "message:" << readData;
}
But the only message I have is:
QIODevice::read (QSerialPort): device not open
message: ""
I don't understand what that mean?
1.Open the serialport,then set the parameters.
PortListener::PortListener(const QString &portName)
{
this->port = new QSerialPort();
port->open(QIODevice::ReadWrite);
port->setPortName(portName);
port->setBaudRate(QSerialPort::Baud9600);
port->setDataBits(QSerialPort::Data8);
port->setParity(QSerialPort::NoParity);
port->setStopBits(QSerialPort::OneStop);
port->setFlowControl(QSerialPort::NoFlowControl);
}
2.Connect the readyRead signal to a slot, and the slot is like this.
void PortListener::readyReadSlot()
{
while (!port.atEnd()) {
QByteArray data = port.readAll();
}
}
This is much more like the QextSerialPort, the following is the code from my application.
void SpClient::start()
{
myComClient = new QextSerialPort(Setting::devCom);
if(myComClient->open(QIODevice::ReadWrite))
{
qDebug() << "open " << Setting::devCom << "as client success";
}
myComClient->setBaudRate(BAUD9600);
myComClient->setDataBits(DATA_8);
myComClient->setParity(PAR_NONE);
myComClient->setStopBits(STOP_1);
myComClient->setFlowControl(FLOW_OFF);
myComClient->setTimeout(50);
....
}
My guess is your code is failing to open the serial port, I have run into permissions issues under linux opening USB ports. You will just need to do a chmod to grant your $USER access mostly.

How to emit a signal when serial port is connected or disconnected in Qt?

I used QSerialPort to communicate with a serial port. But how to emit a signal when it is changed(connected or disconnected)?
OS is win7. Thanks.
I think I have a work-around for your problem (fixed mine at least).
I have a ComPort class that handles all my serial functionality of my GUI. When the user selected a COM-port, then a QTimer is started that checks the status periodically. When the timer is finished, the signal timeout() is emitted for which I wrote a custom slot:
// Custom slot to be called when timer times out.
void ComPort::checkComPortStatus()
{
QSerialPortInfo *info = new QSerialPortInfo;
QList<QSerialPortInfo> list = info->availablePorts();
bool port_still_available = false;
for (QSerialPortInfo &port : list) {
if (port.portName() == serial_port->portName())
port_still_available = true;
}
if (!port_still_available) {
qDebug() << "Selected COM-port," << serial_port->portName() << ", no longer available!";
delete serial_port;
serial_port = nullptr;
qDebug() << "COM-port is deleted.";
delete timer;
timer = new QTimer(this);
qDebug() << "COM-port timer is deleted.";
selectedPort_label->setText("Error: disconnected");
}
}
This, ofcourse, is only useful when the port is still closed. When the port is opened, a standard signal is emited by QT (please consult the documentation):
errorOccurred(QSerialPort::SerialPortError error)
I hope this helps!

QNetworkAccessManager: how to make sure download is finished?

If I do:
QNetworkRequest newRequest(url);
newRequest.setUrl(url);
QNetworkReply *reply = networkManager->get(newRequest);
connect(reply, SIGNAL(finished()), this, SLOT(onRetrievedDownLoadInfo()));
and
void myClass::onRetrievedDownLoadInfo()
{
QNetworkReply *reply = qobject_cast<QNetworkReply*>(QObject::sender());
if (!reply)
{
ui->upgradeLog->appendPlainText("Download failed, invalid context");
return;
}
//Remeber to delete the reply
//---------------------------
reply->deleteLater();
if (reply->error() != QNetworkReply::NoError)
{
ui->upgradeLog->appendPlainText("Download failed, invalid context");
return;
}
reply->readAll();
...
}
Can I say that when the program reaches line
reply->readAll();
All the content replied by the server is successfully received?
Is it possible the reply->readAll(); only returns part of the reply due to network failure?
The error is here:
connect(reply, SIGNAL(finished()), this, SLOT(onRetrievedDownLoadInfo()));
you are not doing it in the correct way. Use a QNetworkAccessManager to check the network is working:
QNetworkConfigurationManager manager;
req.setConfiguration(manager.defaultConfiguration());
connect(&req, SIGNAL(networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility)), this, SLOT(networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility)));

QNetworkAccessManager returning empty results

I am struggling with qnetworkaccessmanager for quite sometime. I googled a lot, but I donot find a solution for this.
I am creating a client using qaccessmanager to talk with a rest server. QNetworkReply is not returning any results. The server is working properly but the client is not returning results. On top of that the server gets called 3 times and sometimes the server is crashing. Hope some one can figure out what is going wrong. I am attaching the client code.
I tried different approches like connecting finished signal of networkaccessmanager, qnetworkreply e.t.c. But all of them ends up in giving the same error "Connection Closed" or the readAll bytearray being empty.
void RestClientCore::ConnectToServer()
{
m_NetworkManager = new QNetworkAccessManager(this);
QUrl url("http://localhost");
url.setPort(5432);
QByteArray postData;
postData.append("/?userid=user");
postData.append("&site=site");
QNetworkReply *reply = m_NetworkManager->post(request,postData);
connect(reply, SIGNAL(readyRead()),this, SLOT(slotReadyRead()));
connect(reply, SIGNAL(finished()), this, SLOT(onRequestCompleted()));
}
void RestClientCore::onRequestCompleted() {
QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
if(reply->error())
{
qDebug() <<reply->bytesAvailable() << reply->errorString();
}
else
{
qDebug() << reply->readAll();
}
reply->deleteLater();
}
void RestClientCore::slotReadyRead()
{
QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
qDebug() << reply->readAll();
}
Thanks in advance
Regards
Rejo

QTcpSocket problem

Writing a chat using Qt. Got a problem. My client's QTcpSocket remains in connecting state, but the server emits newConnection() signal. Network session is not required. Why is that? Here is some code:
ChatClient::ChatClient(QObject *parent)
: QObject(parent) {
tcpSocket = new QTcpSocket(this);
QNetworkConfigurationManager manager;
if (QNetworkConfigurationManager::NetworkSessionRequired
& manager.capabilities()) {
qDebug() << "Network session required";
}
connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(error(QAbstractSocket::SocketError)));
connect(tcpSocket, SIGNAL(connected()),
this, SLOT(requestForID()));
connect(tcpSocket, SIGNAL(readyRead()),
this, SLOT(receiveMessage()));
tcpSocket->connectToHost("192.168.0.100", PORT);
}
void ChatClient::requestForID() {
qDebug() << "Connected, requesting for ID";
QByteArray segment;
QDataStream out(&segment, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_7);
out << (quint16)0 << ID;
out.device()->seek(0);
out << (quint16)(segment.size() - sizeof(quint16));
tcpSocket->write(segment);
}
requestForID() is never being executed
ChatServer::ChatServer(QObject *parent)
: QObject(parent) {
tcpServer = new QTcpServer(this);
if (!tcpServer->listen(QHostAddress::Any, PORT)) {
qDebug() << "Unable to start the server"
<< tcpServer->errorString();
}
qDebug() << "Server port" << tcpServer->serverPort();
connect(tcpServer, SIGNAL(newConnection()),
this, SLOT(processConnection()));
}
void ChatServer::processConnection() {
qDebug() << "Incoming connection";
QTcpSocket *clientSocket = tcpServer->nextPendingConnection();
/*connect(clientSocket, SIGNAL(readyRead()),
this, SLOT(readData()));
readData(clientSocket);
connect(clientSocket, SIGNAL(disconnected()),
clientSocket, SLOT(deleteLater()));*/
QByteArray segment;
QDataStream out(&segment, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_7);
out << (quint16)0 << (quint16)Message
<< "Successfully connected";
out.device()->seek(0);
out << (quint16)(segment.size() - sizeof(quint16));
clientSocket->write(segment);
clientSocket->disconnectFromHost();
}
server displays incoming connection and the client does not emit connected remaining in connecting state, doesnt receive server message as well...
Any ideas?
I had the same problem and I found the reason and a solution.
connectToHost may not be called in the contstructor of the main window directly. Why?
The reason is, that the main message loop is not running yet at this time. Internally QAbstractSocketPrivate::fetchConnectionParameters() gets never called and Qt Socket Timeout Timer thinks connection is never established.
The solution is either to call it "delayed" like in
QMetaObject::invokeMethod(this, "OnDelayedConnect", Qt::QueuedConnection);
Or to call waitForConnected() after connectToHost

Resources