您的位置:首页 > 理论基础 > 计算机网络

QT 通过UDP广播获取网络中所有设备ip地址

2017-02-17 15:44 771 查看
说明:

源码下载地址:http://download.csdn.net/detail/dxzysk/9756965

提供源码下载地址,源码使用说明,先在需要待搜索待获取IP地址的主机上运行server端程序,然后在需要查看搜索结果的主机的Pc上运行client端程序

本文是C++的QT版本例子说明,有时候需要搜索网络中的设备,机器,服务器等,这就要要用到UDP广播的方式,发送广播命令,广播给网络中的每一个主机,该主机接收到广播命令后,立刻发送给请求端自己的设备信息,这里以IP信息为例子。

思路

在每一个设备中部署sever端程序进行监控,client端发送广播命令,每一个server收到命令后,返回给client自己的ip地址信息,给出代码如下,其中,有部分,比如获取ip地址参考来自网络,尊重原创,乐于分享。

server端(QT版)

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_OBJECT

public:
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_H


mainwindow.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 Server_PORT 12811

#define TRY_TIMES 1

MainWindow::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;
}


client端(QT版)

为了便于观察,我们把搜索到的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_OBJECT

public:
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_H


mainwindow.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 1

MainWindow::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);
}


运行结果

1.Server端



2.Client端



说明:这里只运行出来结果搜索结果只有一个,因为我只有一台机器运行了server,如果你条件允许,在多个机器上运行server,在用client搜索,结果就可以搜索到多个了,网络中的所有运行了server的ip都可以搜索到
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  qt udp 广播 ip
相关文章推荐