当前位置:   article > 正文

c++ 局域网远程开机(wol、魔术包)_{"c":"jwoii"}

{"c":"jwoii"}

实现原理很简单,就是udp发个包,共102字节。网卡应该是基于链路层处理的,并不用指定特定的IP和端口,随意设置端口全网广播即可。最后再加个bat脚本 ./WOL.exe xx:xx:xx:xx:xx:xx,放在365*24小时开机的mini小主机上,远程登录小主机,点下bat就可以将大PC开机(PS:主要是因为我大主机太耗电了,开24小时有点受不了),进行控制了~

但在win10下遇到个特别蛋疼的问题,我是Z390-F的主板,网卡是I219-V,但如果不关闭电源管理->快速启动的话,关机后网卡灯始终不亮。。。从微软描述的文档来看,应该是如果是不开启快速启动,关机后应该是进入S5状态,如果开启快速启动,关机后是隐式进入S4状态。目前测试S5、显式S4关机后网卡灯都是亮的,那么从硬件层面上来说,主板应该是完全支持任何模式的,为什么就隐式S4关机后网卡灯不亮,我把BIOS 网卡上所有相关设置都试了下,驱动也更成win10专用最新的了,还是不行。要么是ASUS BIOS上的BUG,要么就是微软的,简直坑得无语。

 

  1. // WOL.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
  2. //
  3. #include "pch.h"
  4. #include <iostream>
  5. #pragma comment(lib,"ws2_32.lib")
  6. using namespace std;
  7. int hexChar2int(char hex)
  8. {
  9. if(hex>='0'&&hex<='9')
  10. {
  11. return hex - '0';
  12. }
  13. else if(hex>='A'&&hex<='Z')
  14. {
  15. return hex - 'A' +10;
  16. }
  17. else if(hex>='a'&&hex<='z')
  18. {
  19. return hex - 'a'+10;
  20. }
  21. return 0;
  22. }
  23. int main(int argc, char* args[])
  24. {
  25. if (argc > 1)
  26. {
  27. char *next_token = NULL;
  28. unsigned char mac[6];
  29. int count = 0;
  30. char* tmp = strtok_s(args[1], ":", &next_token);
  31. while (1)
  32. {
  33. mac[count] = hexChar2int(tmp[0]) * 16 + hexChar2int(tmp[1]);
  34. ++count;
  35. tmp = strtok_s(0, ":", &next_token);
  36. if(tmp==0)
  37. {
  38. break;
  39. }
  40. }
  41. // mac[0] = 0x0C;
  42. // mac[1] = 0x9D;
  43. // mac[2] = 0x92;
  44. // mac[3] = 0xC2;
  45. // mac[4] = 0x56;
  46. // mac[5] = 0xE8;
  47. // 存封包数据,格式为:6个0xFF为一组,16个mac地址为一组.mac地址正好是6个字节,封包总大小=6+16*6=102
  48. unsigned char packet[102] = {0};
  49. struct sockaddr_in addr;
  50. int sockfd, i, j;
  51. const char on = 1;
  52. WSADATA aaa;
  53. // 填充封包数据
  54. for (i = 0; i < 6; i++)
  55. packet[i] = 0xFF;
  56. for (i = 1; i < 17; i++)
  57. {
  58. for (j = 0; j < 6; j++)
  59. {
  60. packet[i * 6 + j] = mac[j];
  61. }
  62. }
  63. // 使用socket发送封包前必须初始化socket
  64. WSAStartup(MAKEWORD(2, 2), &aaa);
  65. // udp方式
  66. sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  67. setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
  68. if (sockfd < 0)
  69. {
  70. printf("setsockopt filed!\n");
  71. return -1;
  72. }
  73. memset(&addr, 0, sizeof(addr));
  74. addr.sin_family = AF_INET;
  75. addr.sin_port = htons(10000);
  76. // 广播地址:255.255.255.255
  77. addr.sin_addr.S_un.S_addr = inet_addr("255.255.255.255");
  78. sendto(sockfd, (const char *)packet, sizeof(packet), 0, (struct sockaddr *)&addr, sizeof(addr));
  79. WSACleanup();
  80. }
  81. return 0;
  82. }
  83. // 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
  84. // 调试程序: F5 或调试 >“开始调试”菜单
  85. // 入门提示:
  86. // 1. 使用解决方案资源管理器窗口添加/管理文件
  87. // 2. 使用团队资源管理器窗口连接到源代码管理
  88. // 3. 使用输出窗口查看生成输出和其他消息
  89. // 4. 使用错误列表窗口查看错误
  90. // 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
  91. // 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/245775
推荐阅读
相关标签
  

闽ICP备14008679号