C++查询ip归属地(QT)

发布时间 2023-03-22 21:13:25作者: Hanpto

以查询ip归属地的例子来学习C++的API接口调用。
常见的API接口可能会给出post及get两种访问方法,我们先学习较为简单的get方法。
首先是找到相关的接口,如https://ip.useragentinfo.com/json
使用get方式访问的话则是https://ip.useragentinfo.com/json?ip=ipaddr
用ApiPost访问结果如图:
image
接下来将其用C++实现。
API接口一般使用http或https协议,我们可以利用Qt的Network模块来实现相关内容。上述接口返回的内容是json,假设我们需要用到其中的province、city、isp及net字段,这就还需要用到Qt的json相关模块对其进行解析。

以下是使用C++查询ip归属地的源码:

点击查看代码
#pragma once
#include<QObject>
#include<QNetworkAccessManager>
#include<QNetworkRequest>
#include<QNetworkReply>
#include<QEventLoop>
#include<QJsonDocument>
#include<QJSonObject>
#include<QJsonValue>

class Network:QObject
{
	Q_OBJECT
public:
	Network(QObject* parent = nullptr);
	QString getIpLabel(QString ip);
	QString getJsonValue(QByteArray replyData, QString key);
private:

};

Network::Network(QObject* parent) :QObject(parent)
{

}

QString Network::getIpLabel(QString ip)
{
    QString queryUrl = "https://ip.useragentinfo.com/json?ip=";
    QString queryIp = queryUrl + ip;
    //负责网络请求的执行
    QNetworkAccessManager* manager = new QNetworkAccessManager();
    //负责完善URL和Header
    QNetworkRequest req;
    req.setUrl(queryIp);

    //发送请求
    QNetworkReply* reply = manager->get(req);

    QEventLoop loop;
    //当reply收到服务器返还的数据时,reply会产生结束信号
    connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    //等待网络传送结果 模拟阻塞状态
    loop.exec();
    QString ipLabel = "";
    //返回的不是空且不是错误时
    if (reply != nullptr && reply->error() == QNetworkReply::NoError)
    {
        QByteArray replyData = reply->readAll();
        QString province = getJsonValue(replyData, "province");
        QString city = getJsonValue(replyData, "city");
        QString isp = getJsonValue(replyData, "isp");
        QString net = GetJsonValue(replyData, "net");
        ipLabel = province + " " + city + " " + isp + " " + net;
        qDebug() << ipLabel;
    }
    else
    {
        qDebug() << reply->error();
    }
    return ipLabel;
}
QString Network::getJsonValue(QByteArray replyData, QString key)
{

    QJsonParseError parseError;
    //先将replyData转换为json文件  (json字符串->json文件)
    QJsonDocument jsonDocument = QJsonDocument::fromJson(replyData, &parseError);
    if (parseError.error == QJsonParseError::NoError)
    {
        //json文件对象存在
        if (jsonDocument.isObject())
        {
            //将json文件转换为json对象
            QJsonObject jsonObject = jsonDocument.object();
            //检查是否存在key该对键值对
            if (jsonObject.contains(key))
            {
                //获取key对应的value
                QJsonValue jsonValue = jsonObject.value(key);
                return jsonValue.toString();
            }
        }
    }
    return "";
}

我们用Qt创建一个简单的窗口程序,界面大致如下:
image

在按钮控件的响应函数中写下如下测试代码:

点击查看代码
    QString ip = ui.ipaddr->toPlainText();
    Network network;
    QString ipLabel = network.GetIpLabel(ip);
    ui.ipinfo->setText(ipLabel);

测试结果:
image