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

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

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

欢迎大家补充说明!

相关推荐
苏三有春2 小时前
PyQt5实战——UTF-8编码器功能的实现(六)
开发语言·qt
Vanranrr2 小时前
C++ QT
java·c++·qt
兆。2 小时前
掌握 PyQt5:从零开始的桌面应用开发
开发语言·爬虫·python·qt
徒步僧13 小时前
ThingsBoard规则链节点:RPC Call Reply节点详解
qt·microsoft·rpc
可峰科技14 小时前
斗破QT编程入门系列之一:认识Qt:初步使用(四星斗师)
开发语言·qt
我喜欢就喜欢15 小时前
基于qt vs下的视频播放
开发语言·qt·音视频
CP-DD15 小时前
Qt的架构设计
qt
阿_旭16 小时前
基于YOLO11/v10/v8/v5深度学习的维修工具检测识别系统设计与实现【python源码+Pyqt5界面+数据集+训练代码】
人工智能·python·深度学习·qt·ai
Bruce小鬼20 小时前
QT创建按钮篇
开发语言·qt
martian66521 小时前
QT开发:掌握现代UI动画技术:深入解析QML和Qt Quick中的动画效果
开发语言·c++·qt·ui