最近遇到这个需求,但是发现一个问题,主机可以使用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//日期:-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//日期:-12-03bool 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,而且跨平台!