1. 程式人生 > >用QT實現Wake On Lan功能(附全部程式原始碼)

用QT實現Wake On Lan功能(附全部程式原始碼)

Wake On Lan也就是遠端喚醒(遠端開機),即通過一臺PC向另一臺已經關機但仍連線電源PC傳送網路資料包,使其開機的功能,前提是兩臺PC同處一個區域網內,且被喚醒方的網絡卡支援網路喚醒功能(現在網絡卡基本上都支援啦)。

原理:PC關閉後,網絡卡仍能獲取電源,一直監聽“magic” packet到來,這種資料包可以是IP、IPX或者其它什麼,其中封裝了特製的位元組序列,一旦收到這種資料包,通過網絡卡與主機板的協作,實現遠端啟動。

Magic包的格式:如果目標主機的MAC地址為 01:02:03:04:05:06的話,包的組成應該如下:

FFFFFFFFFFFF010203040506010203040506010203040506010203040506
010203040506010203040506010203040506010203040506010203040506
010203040506010203040506010203040506010203040506010203040506
010203040506010203040506
由6個16進位制位元組的FF和至少重複16次MAC地址組成。

下面是在QT3中實現的原始碼:

//檔名:main.cpp
#include <qapplication.h>
#include 
"frmMain.h"

int main( int argc, char** argv )
{
    QApplication a( argc, argv );
    Form1 w;
    w.show();
    a.connect( 
&a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) );
    
return a.exec();
}


/****************************************************************************
** Form implementation generated from reading ui file 'frmMain.ui'
**檔名:frmMain.cpp
** Created: 星期四 十月 19 16:30:55 2006
**      by: The User Interface Compiler ($Id: qt/main.cpp   3.3.4   edited Nov 24 2003 $)
**
** WARNING! All changes made in this file will be lost!
***************************************************************************
*/


#include 
"frmMain.h"

#include 
<qvariant.h>
#include 
<qlineedit.h>
#include 
<qpushbutton.h>
#include 
<qlayout.h>
#include 
<qtooltip.h>
#include 
<qwhatsthis.h>
#include 
<qaction.h>
#include 
<qmenubar.h>
#include 
<qpopupmenu.h>
#include 
<qtoolbar.h>
#include 
<qimage.h>
#include 
<qpixmap.h>

#include 
"frmMain.ui.h"
/*
 *  Constructs a Form1 as a child of 'parent', with the
 *  name 'name' and widget flags set to 'f'.
 *
 
*/

Form1::Form1( QWidget
* parent, constchar* name, WFlags fl )
    : QMainWindow( parent, name, fl )
{
    (
void)statusBar();
    
if ( !name )
    setName( 
"Form1" );
    setCentralWidget( 
new QWidget( this"qt_central_widget" ) );

    lineEdit1 
=new QLineEdit( centralWidget(), "lineEdit1" );
    lineEdit1
->setGeometry( QRect( 405027130 ) );

    pushButton2 
=new QPushButton( centralWidget(), "pushButton2" );
    pushButton2
->setGeometry( QRect( 1201108023 ) );

    
// toolbars

    languageChange();
    resize( QSize(
391250).expandedTo(minimumSizeHint()) );
    clearWState( WState_Polished );

    
// signals and slots connections
    connect( pushButton2, SIGNAL( clicked() ), this, SLOT( pushButton2_clicked() ) );
}


/*
 *  Destroys the object and frees any allocated resources
 
*/

Form1::
~Form1()
{
    
// no need to delete child widgets, Qt does it all for us
}


/*
 *  Sets the strings of the subwidgets using the current
 *  language.
 
*/

void Form1::languageChange()
{
    setCaption( tr( 
"Wake On Lan For QT" ) );
    lineEdit1
->setText("00-11-09-9C-CF-A2");
    pushButton2
->setText( trUtf8( "/xe8/xbf/x9c/xe7/xa8/x8b/xe5/xbc/x80/xe6/x9c/xba" ) );
}


/****************************************************************************
** Form interface generated from reading ui file 'frmMain.ui'
**檔名:frmMain.h
** Created: 星期四 十月 19 15:44:26 2006
**      by: The User Interface Compiler ($Id: qt/main.cpp   3.3.4   edited Nov 24 2003 $)
**
** WARNING! All changes made in this file will be lost!
***************************************************************************
*/


#ifndef FORM1_H
#define FORM1_H

#include 
<qvariant.h>
#include 
<qmainwindow.h>

class QVBoxLayout;
class QHBoxLayout;
class QGridLayout;
class QSpacerItem;
class QAction;
class QActionGroup;
class QToolBar;
class QPopupMenu;
class QLineEdit;
class QPushButton;

class Form1 : public QMainWindow
{
    Q_OBJECT

public:
    Form1( QWidget
* parent =0constchar* name =0, WFlags fl = WType_TopLevel );
    
~Form1();

    QLineEdit
* lineEdit1;
    QPushButton
* pushButton2;

public slots:
    
virtualvoid pushButton2_clicked();

protected:

protected slots:
    
virtualvoid languageChange();

}
;

#endif// FORM1_H
/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**檔名:frmMain.ui.h
** If you want to add, delete, or rename functions or slots, use
** Qt Designer to update this file, preserving your code.
**
** You should not define a constructor or destructor in this file.
** Instead, write your code in functions called init() and destroy().
** These will automatically be called by the form's constructor and
** destructor.
****************************************************************************
*/

#include 
"qsocketdevice.h"
#include <qcstring.h> 
#include 
<qmessagebox.h> 

void Form1::pushButton2_clicked()
{
//建立套接字相關物件
 QSocketDevice *MUReceiveSocket;   //套接字物件
 
//QSocketNotifier *MSocketNotifier;     //套接字監聽物件
//初始化套接字相關物件
MUReceiveSocket=new QSocketDevice(QSocketDevice::Datagram);   
//UDP初始化
QHostAddress MyAddress;
QString FakeAddress;
QString SMacAddr
=lineEdit1->text();//網絡卡的mac地址
const Port=0;//目標機器的埠號

//檢查MAC地址是否等於17
if (SMacAddr.length()!=17{
    QMessageBox::warning(
this,"MAC Address ERR","MAC Address must be =17");
    
return
}

//檢查MAC地址是否正確
for (int i=2;i<17;i=i+3{
     
if (SMacAddr[i]!='-'{
          QMessageBox::warning(
this,"MAC Address ERR","MAC Adresse must be like this: 00-D0-4C-BF-52-BA");
         
return;
     }

 }


char MACAddr[6]; 
char MagicPacket[102];//實現遠端開機的Magic包

int j=sscanf(SMacAddr, "%2x-%2x-%2x-%2x-%2x-%2x",
                
&MACAddr[0], &MACAddr[1], &MACAddr[2], &MACAddr[3], &MACAddr[4], &MACAddr[5]);
 
if (j!=6)
 
{
  QMessageBox::warning(
this,"MAC Address ERR","Invalid MAC Adresse!");
  
return;
 }


//把magicpacket陣列前6個字元設定成16進位制的ff
 memset(MagicPacket, 0xff6);

 
int packetsize=6;//初始值是6,不要搞錯了啊。我就是因為大意,把初始會值寫成0,實在是太順手了。
//構建MagicPacket
for (i=0;i<16;i++
{
 memcpy(MagicPacket
+packetsize,MACAddr,6);
 packetsize
+=6;
}


FakeAddress 
="