分享一个自己做的随时随地对内网的电脑进行开机、控制和关机的例子

donghua800 2014-04-12 05:25:58
在公司,或在外地如何才能达到随时随地对宿舍的电脑(在局域网内,IP是192.168.*.*)进行开机、控制和关机呢?通过magic packet可以唤醒局域网的电脑,但是想在公司远程唤醒宿舍的电脑怎么办(不在同一局域网内)?我想到的一个方法是通过手机,让一台手机(先叫手机A)放在宿舍连着wifi,这时候手机和宿舍的那台手机就在同一个局域网了,在公司用手机B给手机A发送一条开机指令的信息,手机A收到信息后发送magic packet就可以唤醒宿舍的电脑了。这时候再通过teamviewer(设置为开机启动),就可以远程控制宿舍的电脑了,也可以通过teamviewer关机。这样就达到随时随地对宿舍的电脑进行开机、控制和关机的目的了。如果你换了新手机,旧手机放在宿舍也没用,不妨用来做这个,方便自己控制自己的电脑。下面是代码,经过在安卓4.2.1和4.0.4下测试可以达到上面所说的想法。
package com.example.testopenos;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.widget.*;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsMessage;

public class SMSBroadcastReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Object[] pdus = (Object[]) intent.getExtras().get("pdus");
for(Object p : pdus){
byte[] pdu = (byte[]) p;
SmsMessage message = SmsMessage.createFromPdu(pdu);
String senderNumber = message.getOriginatingAddress();
String content = message.getMessageBody();
Date date = new Date(message.getTimestampMillis());
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String receiveTime = format.format(date);
System.out.println(senderNumber+"||"+receiveTime+"||"+content);
if(senderNumber.equals("+8613100000000")&&content.equals("YCKJ"))//手机号码前加上+86,YCKJ是短信内容,即命令
{
new Thread(new Runnable()
{
@Override
public void run(){
//magic packet
OpenOS w = new OpenOS();
w.setMac("00-1F-D0-C8-00-00");
w.sendOpenOS();
// abortBroadcast();

}
}).start();
}
}
}

public class OpenOS{
private int port = 9;
private String mac = "00-1F-D0-C8-00-00";
private String ipAddress = "192.168.1.255";//如果你iP地址是192.168.1.*,这里就是192.168.1.255

public OpenOS(){
}

private void setMac(String mac)
{
this.mac = mac;
}

public OpenOS(int port, String mac, String ipAddress){
this.port = port;
this.mac = mac;
this.ipAddress = ipAddress;
}

public void sendOpenOS()
{
InetAddress destHost = null;
DatagramSocket ds = null;
try
{
destHost = InetAddress.getByName(ipAddress);
byte[] destMac = getMacBytes(mac);
byte[] magicBytes = new byte[102];

for (int i = 0; i < 16; i++)
{
for (int j = 0; j < destMac.length; j++)
{
magicBytes[6 + destMac.length * i + j] = destMac[j];
magicBytes[j] = (byte) 0xFF;
}
}

/* // --------------------查看数据报发出的数据---------------------
for (int i = 1; i <= 102; i++)
{
if (((i - 1) % 6) == 0)
{
System.out.println();
}
System.out.print(magicBytes[i - 1] + "===");
}

//System.out.println("port =" + port + ", destHost=" + destHost + ",magicBytes.length = " + magicBytes.length);
*/

DatagramPacket dp = null;
try
{
dp = new DatagramPacket(magicBytes, magicBytes.length, destHost, port);
ds = new DatagramSocket();
ds.send(dp);
}
catch (Exception e)
{
// TODO: handle exception
e.printStackTrace();
}
}
catch (Exception e)
{
// TODO: handle exception
e.printStackTrace();
}
finally
{
if (null != ds)
{
//关闭数据报流
ds.close();
}
}
}

private byte[] getMacBytes(String macStr) throws IllegalArgumentException
{
byte[] bytes = new byte[6];
String[] hex = macStr.split("(\\:|\\-)");
if (hex.length != 6)
{
throw new IllegalArgumentException("Invalid MAC address.");
}
try
{
for (int i = 0; i < 6; i++)
{
bytes[i] = (byte) Integer.parseInt(hex[i], 16);
}
}
catch (NumberFormatException e)
{
throw new IllegalArgumentException("Invalid hex digit in MAC address.");
}
return bytes;
}
}

}

以下是AndroidManifest.xml的内容
<?xml version="1.0" encoding="utf-8" ?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.testopenos" android:versionCode="1" android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" />
- <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme">
- <activity android:name="com.example.testopenos.MainActivity" android:label="@string/app_name">
- <intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
- <receiver android:name=".SMSBroadcastReceiver">
- <intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.RECEIVE_SMS" />
- <!-- 接收短信权限
-->
- <!-- 访问internet权限
-->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
</manifest>



...全文
803 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
donghua800 2014-04-30
  • 打赏
  • 举报
回复
引用 3 楼 tcmakebest 的回复:
好有才的楼主,我也做过局域网开机小工具,原理是一样的
是的,原理是一样。
donghua800 2014-04-15
  • 打赏
  • 举报
回复
引用 5 楼 wjw2066616 的回复:
你这样是通过电脑手动设置ip的把 换了局域网就不好用了。。可以设成通过MAC地址来唤醒。那样无论电脑在哪里都可以了
这就是通过MAC地址来唤醒的,那个IP是广播用的。
wjw2066616 2014-04-15
  • 打赏
  • 举报
回复
你这样是通过电脑手动设置ip的把 换了局域网就不好用了。。可以设成通过MAC地址来唤醒。那样无论电脑在哪里都可以了
chenchencan 2014-04-15
  • 打赏
  • 举报
回复
想法不错 ,值得鼓励
tcmakebest 2014-04-13
  • 打赏
  • 举报
回复
好有才的楼主,我也做过局域网开机小工具,原理是一样的
donghua800 2014-04-12
  • 打赏
  • 举报
回复
引用 1 楼 zanfeng 的回复:
电脑主板要支持这种起动的才可以吧。
很多主板都支持的。
足球中国 2014-04-12
  • 打赏
  • 举报
回复
电脑主板要支持这种起动的才可以吧。

80,351

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧