說明:
源碼下載地址:http://download.csdn.net/detail/dxzysk/9756965
提供源碼下載地址,源碼使用說明,先在需要獲取ip地址的主機上運行server端程序,然后在需要搜索主機的Pc上運行client端程序
本文是C++的QT版本例子說明,有時候需要搜索網絡中的設備,機器,服務器等,這就要要用到UDP廣播的方式,發送廣播命令,廣播給網絡中的每一個主機,該主機搜到廣播命令后,立刻發送給請求端自己的設備信息,這里以IP信息為例子。
思路
在每一個設備中部署sever端程序進行監控,client端發送廣播命令,每一個server收到命令后,返回給client自己的ip地址信息,給出代碼如下,其中,有部分,比如獲取ip地址參考來自網絡,尊重原創,樂于分享。
server端監聽廣播命令”GetIPAddr”,收到命令后就相應,本例中幾面顯示收到的廣播命令和命令來源的ip地址
mainwindow.h #ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>namespace Ui {class MainWindow;}class QLabel;class QUdpSocket;class QListWidget;class MainWindow : public QMainWindow{ Q_OBJECTpublic: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); void initList(); void addBroadcastResItem(QByteArray data, QString ip); void BroadcastGetIpCommand(); void initBroadcastListener(); QString getIp();PRivate: Ui::MainWindow *ui;private: QLabel *label; QListWidget* mlistWidget; ///////////// QUdpSocket * receiver; QUdpSocket * sender;private slots: void processPengingDatagram(); ///////////};#endif // MAINWINDOW_Hmainwindow.cpp#include "mainwindow.h"#include "ui_mainwindow.h"#include<QtNetwork>#include<QLabel>#include <QListWidget>#include <QVBoxLayout>#include <QListWidgetItem>//#define GET_HOST_COMMAND "GetCYHost"#define GET_HOST_COMMAND "GetIPAddr"http://#define LOCAL_PORT 11121#define Server_PORT 12811#define TRY_TIMES 1MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){ ui->setupUi(this); this->setWindowTitle("Server"); initList(); //////////////////////////////// initBroadcastListener();}MainWindow::~MainWindow(){ delete ui;}void MainWindow::initBroadcastListener(){ receiver = new QUdpSocket(this); /////綁定,第一個參數為端口號,第二兒表示允許其它地址鏈接該廣播 receiver->bind(Server_PORT,QUdpSocket::ShareAddress); //readyRead:每當有數據報來時發送這個信號 connect(receiver,SIGNAL(readyRead()),this,SLOT(processPengingDatagram()));}void MainWindow::initList(){ label = new QLabel; label->setFixedWidth(70); label->setText("收到的廣播源:"); mlistWidget = new QListWidget; QVBoxLayout* layout = new QVBoxLayout; QListWidgetItem* lst1 = new QListWidgetItem("broacast command and ip list:", mlistWidget); mlistWidget->insertItem(1, lst1); layout->addWidget(label); layout->addWidget(mlistWidget); QWidget *mainWidget = new QWidget; mainWidget->setLayout(layout); setCentralWidget(mainWidget);}void MainWindow::processPengingDatagram(){ QHostAddress client_address;//聲明一個QHostAddress對象用于保存發送端的信息 //char buf[100];//聲明一個字符數組用于接收發送過來的字符串 //數據報不為空 while( receiver->haspendingDatagrams() ) { quint16 recPort = 0; QByteArray datagram; //datagram大小為等待處理數據報的大小才能就收數據; datagram.resize( receiver->pendingDatagramSize() ); //接收數據報 receiver->readDatagram(datagram.data(),datagram.size(), &client_address, &recPort); //label->setText(datagram); QString strData= datagram; int ret = strData.compare(GET_HOST_COMMAND); if (0 == ret) { addBroadcastResItem(datagram, client_address.toString()); QByteArray datagback = "my ip is:"+getIp().toLatin1(); //QByteArray datagback = "my ip is:192.168.1.123";//+getIp().toLatin1(); receiver->writeDatagram(datagback,datagback.size(),client_address,recPort); } }}void MainWindow::addBroadcastResItem(QByteArray data, QString ip){ QListWidgetItem* lst1 = new QListWidgetItem(data + "/t" + ip, mlistWidget); mlistWidget->insertItem(1, lst1);}//得到主機的ip地址QString MainWindow::getIp(){ //使用allAddresses命令獲得所有的ip地址 QList<QHostAddress> list=QNetworkInterface::allAddresses(); foreach (QHostAddress address,list) { if(address.protocol()==QAbstractSocket::IPv4Protocol) return address.toString(); } return 0;}為了便于觀察,我們把搜索到的Ip地址,在界面上顯示出來,可以用MFC,我這里用QT代替了,感興趣的同學可以用MFC練習一下。QT的代碼如下:
mainwindow.h#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>namespace Ui {class MainWindow;}class QLabel;class QUdpSocket;class QListWidget;class MainWindow : public QMainWindow{ Q_OBJECTpublic: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); void initList(); void addIpItem(QByteArray data); void BroadcastGetIpCommand(); void initBroadcast();private: Ui::MainWindow *ui;private: QLabel *label; QListWidget* mlistWidget; ///////////// QUdpSocket * receiver; QUdpSocket * sender;private slots: void processPengingDatagram(); ///////////};#endif // MAINWINDOW_Hmainwindow.cpp#include "mainwindow.h"#include "ui_mainwindow.h"#include<QtNetwork>#include<QLabel>#include <QListWidget>#include <QVBoxLayout>#include <QListWidgetItem>//#define GET_HOST_COMMAND "GetCYHost"#define GET_HOST_COMMAND "GetIPAddr"#define LOCAL_PORT 11121#define DEST_PORT 12811#define TRY_TIMES 1MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){ ui->setupUi(this); initList(); //////////////////////////////// initBroadcast();}MainWindow::~MainWindow(){ delete ui;}void MainWindow::initBroadcast(){ receiver = new QUdpSocket(this); /////綁定,第一個參數為端口號,第二兒表示允許其它地址鏈接該廣播 receiver->bind(LOCAL_PORT,QUdpSocket::ShareAddress); //readyRead:每當有數據報來時發送這個信號 connect(receiver,SIGNAL(readyRead()),this,SLOT(processPengingDatagram())); BroadcastGetIpCommand();}void MainWindow::BroadcastGetIpCommand(){ //QByteArray datagram = "Hello World!"; QByteArray datagram = GET_HOST_COMMAND; int times = TRY_TIMES; while(times--) { //sender->writeDatagram(datagram.data(),datagram.size(),QHostAddress::Broadcast,1066); receiver->writeDatagram(datagram.data(),datagram.size(),QHostAddress::Broadcast,DEST_PORT); }}void MainWindow::initList(){ label = new QLabel; label->setFixedWidth(70); label->setText("廣播IP地址:"); mlistWidget = new QListWidget; QVBoxLayout* layout = new QVBoxLayout; QListWidgetItem* lst1 = new QListWidgetItem("ip list:", mlistWidget); mlistWidget->insertItem(1, lst1); //mlistWidget->show(); layout->addWidget(label); layout->addWidget(mlistWidget); QWidget *mainWidget = new QWidget; mainWidget->setLayout(layout); setCentralWidget(mainWidget);}void MainWindow::processPengingDatagram(){ //數據報不為空 while( receiver->hasPendingDatagrams() ) { QByteArray datagram; //datagram大小為等待處理數據報的大小才能就收數據; datagram.resize( receiver->pendingDatagramSize() ); //接收數據報 receiver->readDatagram(datagram.data(),datagram.size()); //label->setText(datagram); addIpItem(datagram); }}void MainWindow::addIpItem(QByteArray data){ QListWidgetItem* lst1 = new QListWidgetItem(data, mlistWidget); mlistWidget->insertItem(1, lst1);}
2.Client端 
說明:這里只運行出來結果搜索結果只有一個,因為我只有一臺機器運行了server,如果你條件允許,在多個機器上運行server,在用client搜索,結果就可以搜索到多個了,網絡中的所有運行了server的ip都可以搜索到
新聞熱點
疑難解答