Qt实现ping命令检测主机是否在线

62 篇文章 8 订阅
21 篇文章 0 订阅

最近遇到这个需求,但是发现一个问题,主机可以使用TCP连接但是使用HTTP连接超时(ping超时),于是需要用QT实现ping命令。

网上看了一下,发现竟然没有实现!于是只能自己实现了!

首先需要说明的是,我肯定不希望用QProcess执行"ping.exe”实现,不能跨平台不说,也不优雅。

在网上看到某段TCP代码,给了我很大的启发,原帖在这里,这段代码思路不错,可惜不符合我的要求!

因为我发现实测某些主机可以使用TCP连接但是使用HTTP连接超时(ping超时)。

//判断IP地址及端口是否在线
    static bool IPLive(QString ip, int port, int timeout = 1000) {
        QTcpSocket tcpClient;
        tcpClient.abort();
        tcpClient.connectToHost(ip, port);
        //100毫秒没有连接上则判断不在线
        return tcpClient.waitForConnected(timeout);
    }
//判断是否通外网
    static bool IsWebOk() {
        //能接通百度IP说明可以通外网
        return IPLive("115.239.211.112", 80);
    }

于是我把上述代码修改为http请求,中间走了不少弯路,不断测试调整,这里直接把最终的代码分享出来吧。

//author:autumoon
//联系QQ:4589968
//日期:2020-12-03
    //判断主机是否在线
    static bool IsHostOnline(QString strHostName, int nTimeoutmSeconds = 2000);
    //判断是否通外网,能连接百度IP说明可以通外网
    static bool IsWebOk(){return IsHostOnline("202.108.22.5", 2000);}

实现:

//author:autumoon
//联系QQ:4589968
//日期:2020-12-03
bool HttpDownload::IsHostOnline(QString strHostName, int nTimeoutmSeconds)
{
    QNetworkRequest request(strHostName);
    request.setRawHeader("Content-Type", "charset='utf-8'");
    request.setRawHeader("Content-Type", "application/json");
    QNetworkAccessManager* naManager = new QNetworkAccessManager;

    QEventLoop eventloop;

    QTimer timer;
    timer.singleShot(nTimeoutmSeconds, &eventloop, SLOT(quit()));
    timer.start();

    QNetworkReply* reply = naManager->get(request);
    QMetaObject::Connection conRet = QObject::connect(reply, SIGNAL(finished()), &eventloop, SLOT(quit()));
    Q_ASSERT(conRet);

    eventloop.exec(QEventLoop::ExcludeUserInputEvents);

    if (!timer.isActive())
    {
        //超时,未知状态
        disconnect(reply, SIGNAL(finished()), &eventloop, SLOT(quit()));
        reply->abort();
        reply->deleteLater();

        return false;
    }

    if (reply->error() != QNetworkReply::NoError)
    {
        reply->abort();
        reply->deleteLater();
        return false;
    }

    bool bRes = reply->readAll().length() > 0;
    reply->abort();
    reply->deleteLater();

    return bRes;
}

 成功解决问题!使用了定时器解处理超时的问题!执行本函数相当于执行ping,而且跨平台!

  • 7
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值