说明:
使用说明,先在需要待搜索待获取IP地址的主机上运行server端程序,然后在需要查看搜索结果的主机的Pc上运行client端程序
本文是C++的QT版本例子说明,有时候需要搜索网络中的设备,机器,服务器等,这就要要用到UDP广播的方式,发送广播命令,广播给网络中的每一个主机,该主机接收到广播命令后,立刻发送给请求端自己的设备信息,这里以IP信息为例子。
思路
在每一个设备中部署sever端程序进行监控,client端发送广播命令,每一个server收到命令后,返回给client自己的ip地址信息,给出代码如下,其中,有部分,比如获取ip地址参考来自网络,尊重原创,乐于分享。
server端(QT版)
server端监听广播命令”GetIPAddr”,收到命令后就相应,本例中几面显示收到的广播命令和命令来源的ip地址
- mainwindow.h
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38#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
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106#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
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37#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
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97#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地址的全部内容,更多相关QT内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复