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 服务器)运行。

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

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

欢迎大家补充说明!

相关推荐
委婉待续4 小时前
Qt的学习(一)
开发语言·qt·学习
笨笨马甲4 小时前
Qt Quick Layout功能及架构
开发语言·qt
feiyangqingyun5 小时前
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
c++·qt·udp·gb28181
jllws16 小时前
Qt学习及使用_第1部分_认识Qt---学习目的及技术准备
qt·c++框架
到点就困告6 小时前
海康工业相机SDK二次开发(VS+QT+海康SDK+C++)
数码相机·qt·海康
唐墨12318 小时前
android与Qt类比
android·开发语言·qt
道剑剑非道19 小时前
QT开发技术【ffmpeg + QAudioOutput】音乐播放器 完善
开发语言·qt·ffmpeg
不惑_20 小时前
用 PyQt5 打造一个可视化 JSON 数据解析工具
开发语言·qt·json
誰能久伴不乏1 天前
Qt 开发中的父类与父对象的区别和父对象传递:如何选择 `QWidget` 或 `QObject`?
java·开发语言·qt
誰能久伴不乏1 天前
理解继承与组合的本质:Qt 项目中的设计选择指南
开发语言·qt