Qt实现远程开关机

实现远程控制电脑开关机

1、远程开机

了解一下远程控制开机的原理

在局域网内实现远程开机的原理主要依赖于Wake-on-LAN (WOL) 技术,Wake-on-LAN 是一种网络标准,用于通过网络唤醒计算机。需要确保目标计算机的 BIOS 和网络适配器支持 WoL,并在系统设置中启用该功能。
确保要远程控制的计算机处于同一局域网内,并且其 IP 地址是已知的
了解目标计算机的 MAC 地址,因为发送 WoL 数据包时需要使用它,每台计算机的网卡都有一个唯一的 MAC 地址,用于识别。
在同一局域网内部进行测试,外部网络可能需要路由器配置。

以下案例在局域网内开机已实现控制

cpp 复制代码
#if 1 //两种方法均可实现 任选其一即可
void MainWindow::wakeOnLAN(QString strMac)
{
    QUdpSocket udpSocket;
    /*将字符串MAC转换成十六进制 存入数组*/
    char cstrMacAddr[6];
    /*构建一个魔术唤醒包  6字节0xFF 和  16次的 Mac地址*/
    QByteArray magicPacket;
    bool isOK;
    for(int j = 0;j < 6; j++){
        if(j < 5){
            cstrMacAddr[j] = strMac.mid(strMac.indexOf("-",j*3) - 2,2).toInt(&isOK,16);
            if(false == isOK)
                return ;
        }else if(j == 5){
            cstrMacAddr[j] = strMac.mid(strMac.indexOf("-",j*3 - 1) + 1,2).toInt(&isOK,16);
            if(false == isOK)
                return ;
        }
    }

    /*6个 0xFF*/
    for(int i = 0;i < 6; i++){
        magicPacket[i] = 0xFF;
    }

    /*16个 MAC*/
    for(int k = 0; k < 16; k++)
    {
        for(int l = 0; l < 6; l++)
            magicPacket[(k+1)*6 + l] = cstrMacAddr[l];
    }

    udpSocket.writeDatagram(magicPacket, 102, QHostAddress("255.255.255.255"), 7);
}
#else
void MainWindow::wakeOnLAN(QString strMac)
{
    QByteArray qByte = strMac.toLocal8Bit().toStdString().c_str();
    char chMacAddr[9];
    char chMagicPacket[104];

    const char *lpMacAddr = qByte.data();
    sscanf_s(lpMacAddr, "%2x-%2x-%2x-%2x-%2x-%2x",
            &chMacAddr[0], &chMacAddr[1], &chMacAddr[2],
            &chMacAddr[3], &chMacAddr[4], &chMacAddr[5]);
    memset(chMagicPacket, 0xff, 6);
    int packetsize = 6;
    for (int i = 0; i < 16; i++)
    {
        memcpy(chMagicPacket + packetsize, chMacAddr, 6);
        packetsize += 6;
    }
    QUdpSocket udpSocket;
    /**
    * 端口 9:通常用于 Wake-on-LAN(WoL)功能。这个端口是一个标准的广播端口,许多设备和网络适配器都监听这个端口以接收唤醒信号,    
    * 使用端口 9 时,目标设备会在收到 WoL 数据包时执行唤醒操作。
    * 端口 7: 通常用于 Echo Protocol,主要用于测试和诊断目的,允许发送数据并返回相同的数据。它不是专门用于远程开机的
    * 使用其他端口(如 7)可能不会导致预期的唤醒效果,因为这些端口没有专门设计用于 WoL
    */
    udpSocket.writeDatagram(chMagicPacket, 102, QHostAddress("255.255.255.255"), 7);
}
#endif

2、远程关机

原理及实现步骤

网络连接
远程关机需要通过网络与目标计算机建立连接。常用的协议包括:
复制代码
			SSH(Secure Shell):用于安全地访问远程计算机,执行命令。
			Windows 的 WMI(Windows Management Instrumentation):可以通过网络管理 Windows 系统。
			NetBIOS:在 Windows 网络中使用。
身份验证
复制代码
			在执行关机命令之前,必须对目标计算机进行身份验证。常见的身份验证方法包括:
			用户名和密码:输入正确的凭据以获取权限。
			SSH 密钥:使用公钥和私钥进行无密码登录。
执行关机命令
复制代码
			一旦成功连接并验证身份,客户端将发送一个关机命令到目标计算机。
			在 Linux 中,通常使用 shutdown 命令。
			在 Windows 中,可以使用 shutdown /s /t 0 命令。
权限要求
复制代码
			进行远程关机的用户需要具有足够的权限。在 Windows 系统中,只有管理员用户或具有特定权限的用户才能关机。
网络安全
复制代码
			在实施远程关机时,必须考虑网络安全问题,包括:
			使用加密协议(如 SSH)来保护数据传输。
			防止未授权访问(通过防火墙设置)。
			确保目标计算机的安全配置。
实现代码
cpp 复制代码
#include <QCoreApplication>
#include <QProcess>
#include <QString>
#include <iostream>

void shutdownRemoteComputer(const QString &ip, const QString &username, const QString &password) {
    // 构建 SSH 命令
    QString command = QString("sshpass -p %1 ssh %2@%3 'shutdown now'").arg(password, username, ip);
    
    // 执行命令
    QProcess process;
    process.start(command);
    process.waitForFinished();

    // 获取输出
    QString output = process.readAllStandardOutput();
    QString error = process.readAllStandardError();

    std::cout << "Output: " << output.toStdString() << std::endl;
    std::cout << "Error: " << error.toStdString() << std::endl;
}

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    QString ip = "xxx.xxx.xxx.xxx"; // 替换为目标 IP 地址
    QString username = "xxx_username"; // 替换为目标用户名
    QString password = "xxx_password"; // 替换为目标用户密码

    shutdownRemoteComputer(ip, username, password);

    return a.exec();
}

注意

sshpass:这个示例中使用了 sshpass 来处理密码输入。在某些系统上,你可能需要安装 sshpass 工具。

在 Ubuntu 上可以通过以下命令安装。

powershell 复制代码
sudo apt-get install sshpass
安全性

使用明文密码并不安全,建议使用 SSH 密钥认证,而不是直接在代码中写入密码。

错误处理

此示例没有进行详细的错误处理,实际应用中应根据需要添加适当的错误处理机制。

系统兼容性

上述示例的命令和工具可能在不同的操作系统上有所不同,请根据您的实际情况进行调整。

配置对方电脑

cpp 复制代码
开机进入BIOS
1.Power Management setup ->WakeUpOnLAN 设置为Enable
2.WakeUp By PCI Card 设置为Enable
F10 保存退出 重启之后再关机会发现关机之后网卡灯依然闪烁。

确保防火墙设置不会阻止UDP数据包。

确保局域网内的路由和防火墙配置允许 WoL 和远程控制的流量。

确保目标计算机上有合适的服务(如 SSH 服务器)运行。

你需要有足够权限(如管理员或超级用户)在目标计算机上执行关机命令。

实现方法还有很多很多...

欢迎大家补充说明!

相关推荐
扶尔魔ocy7 小时前
【qt openGL入门笔记】OSG实现飞机模型在网格图上飞行并进行态势标绘(四)
qt·opengl·osg
橙橙笔记11 小时前
QT安卓软件的制作
android·git·qt·软件
芦芭荞11 小时前
QT使用xml模版生成word文档
xml·qt·word
mengzhi啊11 小时前
qt把结构体数据存入json文件
qt·json
kaixin_learn_qt_ing12 小时前
写入二进制文件(Qt)
qt
尘中远14 小时前
QWT7 的科学 Colormap 色彩评估:QwtColorMapPreset 22 种预设的感知均匀性与场景化选
qt·qwt·科学绘图·科学配色
宿州派大星20 小时前
Python实战:PyQt5 + OpenCV + Dlib 打造AI桌面应用
人工智能·python·qt
长沙红胖子Qt1 天前
Qt+TiePieHS3开发笔记(二):HS3发送器发出内置波形、直连示波器,示波器检测内置波形Demo
qt·示波器·tiepiehs3·发生器·同步发射和示波器采集
陈年老古董1 天前
PyQt5 入门指南:环境搭建、PyCharm 外部工具配置与登录界面实战
开发语言·qt·pycharm
zhanghaha13141 天前
Qt 类完整例程【逐词拆解 + 逐步骤执行保姆教程】
开发语言·qt