目的

此博客希望能够对于利用基于qt写的程序, 且功能中能够检测是否有网络, 至于能不能上网(传递数据) 暂无规范化验证。本身是基于如下






从机1

主机

从机2

从机3

从机4


只要保证从机于主机在同一个网络即可(可能会通过一个路由器或者交换机), 至于能不能访问到外网, 无关紧要。

说明

首先网络这方面, 离不开 QNetworkInterface这个类。只有在pro配置

QT  += network

你才能使用这个接口。

那如何使用这个去检测是否有网.
关键性几点:

1: QNetworkInterface 是否有效
2: QNetworkInterface 中flags 判断是否QNetworkInterface::IsUp && QNetworkInterface::IsRunning
3: QNetworkInterface 中type 判断是否QNetworkInterface::Wifi || QNetworkInterface::Ethernet

核心代码:

QList<QNetworkInterface> interfaceList = QNetworkInterface::allInterfaces();
    foreach(QNetworkInterface interfaceItem, interfaceList)
    {
        if(interfaceItem.isValid() && (interfaceItem.flags().testFlag(QNetworkInterface::IsUp)) && (interfaceItem.flags().testFlag(QNetworkInterface::IsRunning))){
            if(QNetworkInterface::Wifi == interfaceItem.type() || QNetworkInterface::Ethernet == interfaceItem.type()){
                valid = true;
                break;
            }
        }
    }

qt 文档中对 enum QNetworkInterface::InterfaceType 说明如下

Specifies the type of hardware (PHY layer, OSI level 1) this interface is, if it could be determined. 
Interface types that are not among those listed below will generally be listed as Unknown, though future versions of Qt may add new enumeration values.
如果可以确定,则指定此接口的硬件类型(PHY层,OSI级别1 -- 也就是物理层)。不在下面列出的接口类型中的接口类型通常会被列为未知,尽管Qt的未来版本可能会添加新的枚举值。

具体有三种类型解释是, 对于QNetworkInterface::Virtual 我是每没太明白因此没用。 如果有网友知道的, 望可以告诉我下。

类型

说明

QNetworkInterface::Virtual

A type of interface determined to be virtual, but not any of the other possible types. For example, tunnel interfaces are (currently) detected as virtual ones.(一种被确定为虚拟的接口类型,但不是任何其他可能类型。例如,通道接口(当前)被检测为虚拟接口。)

QNetworkInterface::Ethernet

IEEE 802.3 Ethernet interfaces, though on many systems other types of IEEE 802 interfaces may also be detected as Ethernet (especially Wi-Fi). (IEEE 802.3以太网接口,尽管在许多系统上,其他类型的IEEE 802接口也可以被检测为以太网(尤其是Wi-Fi)。)

QNetworkInterface::Wifi

IEEE 802.11 Wi-Fi interfaces. Note that on some systems, QNetworkInterface may be unable to distinguish regular Ethernet from Wi-Fi and will not return this enum value.(IEEE 802.11 Wi-Fi接口。请注意,在某些系统上,QNetworkInterface可能无法区分常规以太网和Wi-Fi,并且不会返回此枚举值)

扩展

第一种:只需要判断网络是否有连接,不一定能上网

这个很简单,直接通过Qt的类QNetworkConfigurationManager自带的函数就可以判断(该方法也适用于Android平台):

bool CommonParameter::isNetWorkOnline()
{
    QNetworkConfigurationManager mgr;
    return mgr.isOnline();
}

第二种:判断是否能上网

这种方式是检查是否连接互联网,原理:通过访问指定的网站,如果能访问成功表示已正常连接。

void CommonParameter::checkNetWorkOnline()
{
    QHostInfo::lookupHost("www.baidu.com",this,SLOT(onLookupHost(QHostInfo)));
}

void CommonParameter::onLookupHost(QHostInfo host)
{
    if (host.error() != QHostInfo::NoError) {
        qDebug() << "Lookup failed:" << host.errorString();
        //网络未连接,发送信号通知
        emit sigLookUpHostResult(false);
    }
    else{
        emit sigLookUpHostResult(true);
    }
}

通过静态函数QHostInfo::lookupHost访问指定网络后会将结果返回到槽里面,然后再将结果发送信号出去。

使用 Wininet.dll 库

#include <QLibrary>

typedef bool(*ConnectFun)(int* lpdwFlags, int  dwReserved);

void Widget::on_pushButton_clicked()
{
    QLibrary lib("Wininet.dll");
    if (lib.load())
    {
        bool bOnline = false;//是否在线
        int  flags;

        //获取dll库中的函数InternetGetConnectedState函数地址`
        ConnectFun  myConnectFun = (ConnectFun)lib.resolve("InternetGetConnectedState");

        //判断是否连网
        bOnline = myConnectFun(&flags, 0);
        if(bOnline)
            qDebug() << __FUNCTION__ << "isOnline = true";
        else
            qDebug() << __FUNCTION__ << "isOnline = false";
    }
}