Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1035295
  • 博文数量: 178
  • 博客积分: 3629
  • 博客等级: 中校
  • 技术积分: 1850
  • 用 户 组: 普通用户
  • 注册时间: 2005-02-23 21:21
文章分类

全部博文(178)

文章存档

2025年(1)

2021年(1)

2020年(5)

2019年(4)

2018年(7)

2017年(1)

2016年(4)

2014年(1)

2013年(8)

2012年(10)

2011年(50)

2009年(12)

2008年(10)

2006年(56)

2005年(8)

分类: BSD

2025-01-10 13:47:25

网上找了一堆,不是没有这个功能,是需要安装APP和注册,太麻烦。
于是DIY一个,在macos 15下clang编译通过。实测可以唤醒家里的主机。

编程语言:C
编程环境:MAC XCode16.2 
适用网络:在外面经过家里路由器唤醒家里主机。
家里局域网唤醒可以变通实现:把IP 设为广播地址,把端口port设为9,目标MAC不变。

//

//  main.c

//  WOL

//

//  Created by 正心以中 on 2025/1/9.

//


#include

#include

#include

#include

#include

#include

#include

#include


// 发送唤醒魔术包的函数

void send_wake_on_lan(const char *ip, int port, const char *mac) {

    int sockfd;

    struct sockaddr_in server_addr;

    unsigned char magic_packet[102];  // 构造魔术包(6字节重复16次 + 6字节的头部)


    //函数:将 MAC 地址字符串转换为字节数组

    unsigned char mac_bytes[6];

    sscanf(mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",

               &mac_bytes[0], &mac_bytes[1], &mac_bytes[2], &mac_bytes[3], &mac_bytes[4], &mac_bytes[5]);


    // 填充魔术包

    memset(magic_packet, 0xFF, 6);

    for (int i = 0; i < 16; i++) {

        memcpy(magic_packet + 6 + i * 6, mac_bytes, 6);

    }


    // 创建UDP套接字

    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {

        perror("Socket creation failed");

        exit(EXIT_FAILURE);

    }


    // 设置服务器地址结构体

    memset(&server_addr, 0, sizeof(server_addr));

    server_addr.sin_family = AF_INET;

    server_addr.sin_port = htons(port);

    if (inet_pton(AF_INET, ip, &server_addr.sin_addr) <= 0) {

        perror("Invalid address/Address not supported");

        exit(EXIT_FAILURE);

    }


    // 发送魔术包

    if (sendto(sockfd, magic_packet, sizeof(magic_packet), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {

        perror("Sendto failed");

        exit(EXIT_FAILURE);

    }


    close(sockfd);

}


// 解析URL获取IP地址的函数

char* url_to_ip(const char *url) {

    struct hostent *he;

    struct in_addr **addr_list;

    he = gethostbyname(url);

    if (he == NULL) {

        herror("gethostbyname");

        return NULL;

    }

    addr_list = (struct in_addr **)he->h_addr_list;

    return inet_ntoa(*addr_list[0]);

}


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

    if (argc!= 4) {

        printf("Usage: %s \n", argv[0]);

        return 1;

    }


    const char *url = argv[1];

    int port = atoi(argv[2]);

    const char *mac = argv[3];



    char *ip = url_to_ip(url);


    if (ip == NULL) {

        return 1;

    }


    send_wake_on_lan(ip, port, mac);

    printf("Wake-on-LAN packet sent to %s:%d for MAC %s\n", ip, port, mac);

   // free(ip);

    //ip = NULL;

    return 0;

}



运行三个参数
url: 使用ddns( 路由自带)域名。目的是为了得到路由地址方便(需要外网地址才可以)。
port : 端口映射到被唤醒主机,路由设置,{BANNED}最佳好IP绑定被唤醒主机。
MAC: 必须使用 AA:BB:CC:DD:EE:FF  格式


阅读(8) | 评论(0) | 转发(0) |
1

上一篇:mac几个串口工具

下一篇:没有了

给主人留下些什么吧!~~