遠端喚醒電腦 magic package WOW

下載的GUI wol小程式(on github 好地方),就真的只能Wake On Lan的樣子(恩...的樣子),然後老爸載的手機app竟然......WOW(Wake On Wan),跪了。


看著我小小的sony ericsson xperia,我不忍心再加重它的負擔,即使是小小幾KB的app也不要。就在山窮水盡之時,老爸說:何不自己寫一個,應該不會太難。


對啊,之前學過socket,送封包應該不會太難,而且我之前有寫成庫,應該很快。


magic package的原理是廣播欲喚醒裝置的mac(相當於身分證字號)十六次,WOL很直觀,就直接廣播就好了,一般是在9port使用UDP。


WOW呢?有兩種方式,一是VPN,一是連接埠轉發,就是轉port啦。由於還不會設定VPN,所以先設定port囉!


192.168.1.1 -> 進路由器(我家是用sapido rb 1800) -> NAT -> 虛擬伺服器





設定完後,我就啪啪啪啪,嗯?mac 是送string就可以嗎?啪啪啪啪,送。沒反應 QQ


沒辦法,上網查...原來udp socket寫法不同 mac 也要用byte來送啊... 雙手奉上參考 (char 剛剛好是一byte 因為C沒有byte此種資料型態)


儘管寫的是WOL,只要IP改成實體IP就好了,之後port再用指定連接埠轉發的那一個,就可以達到WOW的效果了。


查一下實體IP,如果沒有申請靜態的話,每次數據機關掉或斷掉,便會重抓,可以寫個常駐程式上傳位址,或者直接申請ddns(這裡有免費的)


參考教程做一點修改




//code reference https://shadesfgray.wordpress.com/2010/12/17/wake-on-lan-how-to-tutorial/
//thx to Shades of Gray's blogger !
//I made some changes and make wol to wow by setting my router.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
/* select one to define
#define IP "www.yourdns.ddns.net"//wan
#define IP "211.74.180.72"//wan
#define IP "192.168.1.10"//lan
*/
unsigned char package[102];
unsigned char mac[6];
int main(void){
int i;
//make package
for(i = 0 ; i < 6 ; i++)
package[i] = 0xff;
//your device's mac
mac[0] = 0x38;
mac[1] = 0x60;
mac[2] = 0x77;
mac[3] = 0xc7;
mac[4] = 0x53;
mac[5] = 0x4e;
//package end
for(i = 1 ; i <= 16 ; i++)
memcpy(&package[i*6] , &mac , 6 * sizeof(unsigned char));
int udpSocket;
struct sockaddr_in udpClient, udpServer;
int broadcast = 1;
udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
//broadcast setting
if (setsockopt(udpSocket, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) == -1) {
perror("setsockopt (SO_BROADCAST)");
exit(1);
}
udpClient.sin_family = AF_INET;
udpClient.sin_addr.s_addr = INADDR_ANY;
udpClient.sin_port = 0;
bind(udpSocket, (struct sockaddr*)&udpClient, sizeof(udpClient));
//server setting
udpServer.sin_family = AF_INET;
udpServer.sin_addr.s_addr = inet_addr(IP);
udpServer.sin_port = htons(9);
//send package
sendto(udpSocket, &package, sizeof(unsigned char) * 102, 0, (struct sockaddr*)&udpServer, sizeof(udpServer));
return 0;
}
view raw sendMP.c hosted with ❤ by GitHub

留言

這個網誌中的熱門文章

[Antergos] disable touchpad

活著。