AUST自助上网_CPP

longxin liu 发布于 2024-11-10 106 次阅读


#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <curl/curl.h>
#include <thread>
#include <atomic>
#include <chrono>

// 读取 .config 文件,并将配置存储到 map 中
std::map<std::string, std::string> readConfigFile(const std::string& filename) {
    std::map<std::string, std::string> config;
    std::ifstream file(filename);

    if (!file.is_open()) {
        std::cerr << "无法打开文件: " << filename << std::endl;
        return config;
    }

    std::string line;
    while (std::getline(file, line)) {
        if (line.empty() || line[0] == '#') continue;

        size_t delimiterPos = line.find('=');
        if (delimiterPos != std::string::npos) {
            std::string key = line.substr(0, delimiterPos);
            std::string value = line.substr(delimiterPos + 1);

            key.erase(0, key.find_first_not_of(" \t"));
            key.erase(key.find_last_not_of(" \t") + 1);
            value.erase(0, value.find_first_not_of(" \t"));
            value.erase(value.find_last_not_of(" \t") + 1);

            config[key] = value;
        }
    }
    file.close();
    return config;
}

// 写入 .config 文件
void writeConfigFile(const std::string& filename, const std::map<std::string, std::string>& config) {
    std::ofstream file(filename);

    if (!file.is_open()) {
        std::cerr << "无法打开文件: " << filename << std::endl;
        return;
    }

    for (const auto& entry : config) {
        file << entry.first << "=" << entry.second << std::endl;
    }

    file.close();
}

// 收集服务器响应内容
size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
    ((std::string*)userp)->append((char*)contents, size * nmemb);
    return size * nmemb;
}

// 发送 POST 请求的函数
void sendPostRequest(const std::string& url, const std::string& user, const std::string& password, const std::string& server) {
    CURL* curl;
    CURLcode res;
    long http_code = 0;

    std::string data = "callback=dr1003&DDDDD=" + user + "@" + server +
        "&upass=" + password + "&0MKKey=123456&R1=0&R3=0&R6=0&para=00&v6ip=&v=";

    std::cout << "发送的数据: " << data << std::endl;

    std::string response; // 用于存储服务器响应
    curl = curl_easy_init();
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl, CURLOPT_POST, 1L);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());

        // 设置Content-Type头
        struct curl_slist* headers = nullptr;
        headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

        // 设置接收响应的回调
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

        res = curl_easy_perform(curl);
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);

        if (res != CURLE_OK) {
            std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
        }
        else {
            std::cout << "HTTP 状态码: " << http_code << std::endl;
        }

        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
    }
    else {
        std::cerr << "初始化 curl 失败!" << std::endl;
    }
}

// 使用 HTTP 状态码验证是否连接到外部网络
bool checkInternetConnection() {
    CURL* curl;
    CURLcode res;
    long http_code = 0;
    bool isConnected = false;

    curl = curl_easy_init();
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "http://www.baidu.com");
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, 2L); // 设置超时为 2 秒
        curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); // 仅请求头部
        res = curl_easy_perform(curl);

        if (res == CURLE_OK) {
            curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
            if (http_code == 200) {
                isConnected = true;
            }
        }

        curl_easy_cleanup(curl);
    }
    return isConnected;
}

// 检查用户输入并判断是否退出程序
std::atomic<bool> stopFlag(false);
void userInputThread() {
    std::string userInput;
    while (!stopFlag) {
        std::cin >> userInput;
        if (userInput == "q" || userInput == "Q") {
            stopFlag = true;
        }
    }
}

int main() {
    std::string configFileName = ".config";
    std::map<std::string, std::string> config = readConfigFile(configFileName);

    if (config.empty()) {
        std::cout << "未找到配置文件或配置为空,请输入以下信息以生成配置文件:" << std::endl;

        std::cout << "学号: ";
        std::cin >> config["user"];
        std::cout << "密码: ";
        std::cin >> config["password"];
        std::cout << "运营商 (电信:aust, 联通:unicom, 移动:cmcc): ";
        std::cin >> config["server"];
        config["url"] = "http://10.255.0.19/a79.htm";
        std::cout << "配置文件已生成。" << std::endl;

        writeConfigFile(configFileName, config);
    }

    std::string user = config["user"];
    std::string password = config["password"];
    std::string server = config["server"];
    std::string url = config.count("url") > 0 ? config["url"] : "http://10.255.0.19/a79.htm";

    std::thread inputThread(userInputThread);

    // 主循环检查网络连接状态
    while (!stopFlag) {
        if (checkInternetConnection()) {
            std::cout << "\r已连接到Internet" << std::flush;
        }
        else {
            std::cout << "\r未连接到Internet, 正在尝试重新连接..." << std::flush;
            sendPostRequest(url, user, password, server);
        }
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }

    if (inputThread.joinable()) {
        inputThread.join();
    }

    return 0;
}

此作者没有提供个人介绍
最后更新于 2024-11-10