1. 程式人生 > >C#實現遠端開機(區域網測試通過)

C#實現遠端開機(區域網測試通過)

首先介紹相關知識。
UDP協議
UDP 是User Datagram Protocol的簡稱, 中文名是使用者資料報協議,是OSI(Open System Interconnection,開放式系統互聯) 參考模型中一種無連線的傳輸層協議,提供面向事務的簡單不可靠資訊傳送服務。
下面是UDP與TCP的一些區別:
**A)**UDP是無連線的。相比於TCP協議,UDP協議在傳送資料前不需要建立連線,當然也就沒有釋放連線。
**B)**UDP是盡最大努力交付的。也就是說UDP協議無法保證資料能夠準確的交付到目的主機。也不需要對接收到的UDP報文進行確認。
**C)**UDP是面向報文的。也就是說UDP協議將應用層傳輸下來的資料封裝在一個UDP包中,不進行拆分或合併。因此,運輸層在收到對方的UDP包後,會去掉首部後,將資料原封不動的交給應用程序。
**D)**UDP沒有擁塞控制。因此UDP協議的傳送速率不送網路的擁塞度影響。
**E)**UDP支援一對一、一對多、多對一和多對多的互動通訊。
**F)**UDP的頭部佔用較小,只佔用8個位元組。

阻塞與非阻塞
簡單理解為需要做一件事能不能立即得到返回應答,如果不能立即獲得返回,需要等待,那就阻塞了,否則就可以理解為非阻塞。
阻塞和非阻塞關注的是程式在等待呼叫結果(訊息,返回值)時的狀態.
阻塞呼叫是指呼叫結果返回之前,當前執行緒會被掛起。呼叫執行緒只有在得到結果之後才會返回。
非阻塞呼叫指在不能立刻得到結果之前,該呼叫不會阻塞當前執行緒。
舉個栗子:
你問書店老闆有沒有《深入淺出MFC》這本書,你如果是阻塞式呼叫,你會一直把自己“掛起”,直到得到這本書有沒有的結果;如果是非阻塞式呼叫,你不管老闆有沒有告訴你,你自己先一邊去玩了, 當然你也要偶爾過幾分鐘check一下老闆有沒有返回結果。

IPAddress類
提供網際協議地址
IPAddress.Broadcast 欄位
提供IP廣播地址,此欄位為只讀。
語法:public static readonly IPAddress Broadcast
Broadcast欄位等效於以點分隔的四部分表示法格式的255.255.255.255

UdpClient類
提供使用者資料報(UDP)網路服務
語法:public class UdpClient : IDisposable
UdpClient類提供了一些簡單的方法,用於在阻止模式下發送和接受無連線UDP資料報。
您可以選擇使用下面兩種方法之一來建立預設遠端主機:
1.使用遠端主機名和埠號作為引數建立 UdpClient 類的例項。
2.建立 UdpClient 類的例項,然後呼叫 Connect 方法。

UdpClient.Connect 方法 (IPAddress, Int32)
使用指定的 IP 地址和埠號建立預設遠端主機。
名稱空間: System.Net.Sockets
程式集: System(在 System.dll 中)
語法:public void Connect(IPAddress addr, int port)
引數:
addr 要將資料傳送到的遠端主機的IPAddress
port 要將資料傳送到的埠號。

如果在呼叫 Send 方法時指定了 IPAddress.Broadcast ,則可以將資料廣播到預設的廣播地址:255.255.255.255。
UdpClient.Send方法(Byte[], Int32)
將UDP資料報傳送到遠端主機。
語法:public int Send(byte[] dgram, int bytes)
引數:
dgram Byte型別的陣列,它指定您打算以位元組資料形式傳送的UDP資料報
bytes 資料報中的位元組數
返回值:已傳送的位元組數。
呼叫此方法將資料報傳送在Connect方法中建立的遠端主機,並返回傳送的位元組數。如果在呼叫此過載之前未呼叫Connect,則Send方法引發異常(SockeException)。

MAC地址
MAC(Media Access Control或者Medium Access Control)地址,意譯為媒體訪問控制,或稱為實體地址、硬體地址,用來定義網路裝置的位置。在OSI模型中,第三層網路層負責 IP地址,第二層資料鏈路層則負責 MAC地址。因此一個主機會有一個MAC地址,而每個網路位置會有一個專屬於它的IP地址。 MAC地址是網絡卡決定的,是固定的。
談起MAC地址,不得不說一下IP地址。IP地址工作在OSI參考模型的第三層網路層。兩者之間分工明確,默契合作,完成通訊過程。IP地址專注於網路層,將資料包從一個網路轉發到另外一個網路;而MAC地址專注於資料鏈路層,將一個數據幀從一個節點傳送到相同鏈路的另一個節點。

獲取本機MAC地址
執行cmd,鍵入命令 ipconfig/all

遠端喚醒
遠端開機Wake onLAN(WOL),俗稱遠端喚醒,是現在很多網絡卡都支援的功能。而遠端喚醒的實現,主要是向目標主機發送特殊格式的資料包,是AMD公司製作的MagicPacket這套軟體以生成網路喚醒所需要的特殊資料包,俗稱魔術包(Magic Packet)。MagicPacket格式雖然只是AMD公司開發推廣的技術,並非世界公認的標準,但是仍然受到很多網絡卡製造商的支援,因此許多具有網路喚醒功能的網絡卡都能與之相容。

原理上我們不用深入,實現上是發一個BroadCast包,包的內容包括以下資料就可以了。FF FF FF FF FF FF,6個FF是資料的開始,緊跟著16次MAC地址就可以了。

有了以上的基礎知識,就要開始我們的專案了。用計算機(pc-A)喚醒區域網中的計算機(pc-B)。
設定pc-B
首先需要進行BIOS和網絡卡設定,啟動計算機,進入BIOS引數設定。選擇電源管理設定“Power Management Setup”選項,將“Wake up on LAN”項和“Wake on PCI Card”項均設定為“Enable”,啟用該計算機的遠端喚醒功能。
獲取pc-B的Mac地址
通過命令列輸入ipconfig/all可以得到pc-B的地址 00 0B 2F 70 40 9E

編碼實現

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Net.Sockets;
using System.Net;
namespace 遠端喚醒開機
{
///
/// MainWindow.xaml 的互動邏輯
///
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public static void WakeUp(byte[] mac)
{
UdpClient client = new UdpClient();
client.Connect(IPAddress.Broadcast, 9090);
//MessageBox.Show(IPAddress.Broadcast.ToString());
byte[] packet = new byte[17 * 6];
for (int i = 0; i < 6; i++)
packet[i] = 0xFF;
for (int i = 1; i <= 16; i++)
for (int j = 0; j < 6; j++)
packet[i * 6 + j] = mac[j];
int result = client.Send(packet, packet.Length);
}
private void button1_Click(object sender, RoutedEventArgs e)
{
byte[] mac = new byte[6];
mac[0] = 0x00;
mac[1] = 0x0B;
mac[2] = 0x2F;
mac[3] = 0x70;
mac[4] = 0x40;
mac[5] = 0x9E;
WakeUp(mac);
}
}
}
---------------------
作者:一蓑煙雨1989
來源:CSDN
原文:https://blog.csdn.net/wangshubo1989/article/details/48286383
版權宣告:本文為博主原創文章,轉載請附上博文連結!