数码产品种类越来越多,让人目不暇接。当多种数码产品以及电脑、网络等放到一起的时候,就是我们充分发挥想象力,创造各种奇特的应用的时候了。

就拿这开机说起吧。当只有一台电脑的时候,开机是件再普通不过的事情了,轻轻按一下电源,开机就实现了。而当有两台电脑时,一台电脑已经打开了,现在我要打开另一台,是不是一定要站起来,走过去,按下电源呢?答案就不一定了。这里我要举两个例子,一是用一台电脑为另一台电脑开机,二是用手机让电脑开机。

如果要实现电脑的远程开机,一是要电脑的电源支持,二是要主板支持,三是要网卡支持,四是要控制远程开机的电脑与被控制的电脑在同一局域网内。幸运的是,现在大多数电源与集成网卡的主板是满足前三个条件的,只不过可能需要再BIOS里做些设置,例如要允许网卡BIOS、允许Wake up on LAN等。而第四个条件,对于数字家庭来说就更满足了。一个典型的scenario是:一个家庭有一台台式机和一台笔记本电脑,台式机通过网线连到无线路由器上,而笔记本则通过无线网上网。这家主人抱着笔记本来到厕所大号,突然想访问台式机上的一个文件,这时就可以通过运行一个远程开机软件来远程打开台式机,然后访问里面的资源。这种远程开机软件原理非常简单,完全可以自己写的,例如下面就是一段完整的实现远程开机的代码:(VC6编译)


1.        WSADATA data;
2. 
3. //初始化socket环境 
4. 
5. //创建一个UDP SOCKET 
6. 
7. bool
8. 
9. char*)&val, sizeof(val));//设置广播模式 
10. 
11. char mac[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}; //假设你的台式机网卡的MAC地址是00-11-22-33-44-55 
12. 
13. char buf[102];       //准备数据包,远程开机其实就是发送一个102字节长的UDP广播包 
14. 
15. //前六个字节固定都是0xff 
16. 
17. for(int i = 0; i < 16; i++)       //之后把MAC地址重复16遍 
18. 
19.               memcpy(&buf[i * 6 + 6], mac, 6);
20. 
21.        sockaddr_in to;
22. 
23.        to.sin_family = AF_INET;
24. 
25. //端口无所谓的 
26. 
27. //发送数据到广播地址 
28. 
29. sizeof(to));       //发送。到这步时台式机就启动了 
30. 
31. //关闭SOCKET 
32.

稍有点C++和Winsock编程的基础的人应该很容易看懂这段代码,注意编译之前要include <winsock.h>,并且加上对ws2_32.lib的引用。把这段代码编译成一个基于控制台的EXE文件,拷到WINDOWS目录下,之后想开机时就可以直接按WIN+R,输入你的EXE的名字,就可以开机了。

另一种情况是你的笔记本电脑没有打开,但你拥有一台支持Wi-Fi的手机,那么你一样可以通过手机来远程打开电脑。这里以可以运行.Net程序的Windows Mobile环境为例,把上面的C++代码直接翻译成C#代码:


1. static void
2. 
3.               {

4. 
5. new
6. 
7. //     s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, new byte[] { 1}); 
8. 
9. byte[] data = new byte[102];
10. 
11. for(int
12. 
13.                             data[i] = 0xff;
14. 
15. for(int
16. 
17.                      {

18. 
19.                             data[i * 6 + 6] = 0x00;
20. 
21.                             data[i * 6 + 7] = 0x11;
22. 
23.                             data[i * 6 + 8] = 0x22;
24. 
25.                             data[i * 6 + 9] = 0x33;
26. 
27.                             data[i * 6 + 10] = 0x44;
28. 
29.                             data[i * 6 + 11] = 0x55;
30. 
31.                      }
32. 
33. new System.Net.IPEndPoint(                          new
34. 
35.                      s.SendTo(data, addr);
36. 
37.                      s.Close();
38. 
39.               }
40.

容易发现这段代码的原理与之前的大致相同,唯一不同的就是被注释掉的一行,它本来是用来设计Socket的广播模式的,在PC上运行时这一行是必须的,否则在调用SendTo方法时被有异常,但在手机上运行时这一行是不能要的,原因是SocketOptionName.Broadcast这个选项不受.NET Compact Framework支持,而不设置这个选项在手机一样可以发出广播包。

把这段C#代码编译成EXE文件,放到Windows Mobile环境下运行一下,果然成功。由此,我们进行了数字家庭的大门,为以后坐在沙发上什么都能干做出了迈出了第一步。