通过UDP广播获取网络中所有设备ip地址
说明:
源码下载地址:http://download.csdn.net/detail/dxzysk/9756896
源码使用说明,先在需要获取IP地址的主机上运行server端程序,然后在需要搜索主机的Pc上运行client端程序
本文是windows版,VC++,在VS2010环境下调试成功。有时候需要搜索网络中的设备,机器,服务器等,这就要要用到UDP广播的方式,发送广播命令,广播给网络中的每一个主机,该主机或设备接收到广播命令后,立刻发送给请求端自己的设备信息,这里以IP信息为例子。
思路
在每一个设备中部署sever端程序进行监控,client端发送广播命令,每一个server收到命令后,返回给client自己的ip地址信息,给出代码如下,其中,有部分,比如获取ip地址参考来自网络,尊重原创,乐于分享。
server端(windows控制台程序)
server端监听广播命令”GetIPAddr”,收到命令后就相应
#include <WinSock2.h>
#include <stdio.h>
#include <iostream>
using namespace std; #pragma comment(lib, "ws2_32.lib") #define GET_HOST_COMMAND "GetIPAddr"
const int MAX_BUF_LEN = 255;
#define SERVER_PORT 12811 //只返回一个ip地址
bool GetLocalIP(char* ip)
{ //1.初始化wsa WSADATA wsaData; int ret=WSAStartup(MAKEWORD(2,2),&wsaData); if (ret!=0) { return false; } //2.获取主机名 char hostname[256]; ret=gethostname(hostname,sizeof(hostname)); if (ret==SOCKET_ERROR) { return false; } //3.获取主机ip HOSTENT* host=gethostbyname(hostname); if (host==NULL) { return false; } //4.转化为char*并拷贝返回 strcpy(ip,inet_ntoa(*(in_addr*)*host->h_addr_list)); return true;
} bool doServer(){int m_nPort = SERVER_PORT;SOCKET sClient;sockaddr_in clientAddr,bindAddr;WSADATA wsdata;//启动SOCKET库,版本为2.0WORD wVer=MAKEWORD(2,0);if( 0 != WSAStartup(wVer,&wsdata) ){//AfxMessageBox(L"Not Support Socket2.0");return false;}//用UDP初始化套接字sClient=socket(AF_INET,SOCK_DGRAM,0);//设置该套接字为广播类型,BOOL optval=TRUE;bindAddr.sin_family=AF_INET;bindAddr.sin_addr.s_addr=htonl(INADDR_ANY);bindAddr.sin_port=htons(m_nPort);setsockopt(sClient,SOL_SOCKET,SO_BROADCAST,(char FAR *)&optval,sizeof(optval));bind(sClient,(sockaddr *)&bindAddr,sizeof(sockaddr_in));int nAddrLen = sizeof(SOCKADDR); char buf[256] = {0};int fromlength=sizeof(SOCKADDR);printf("the server is start.\n");char ipaddr[30] = {0};char buff[MAX_BUF_LEN] = ""; if (GetLocalIP(ipaddr)){sprintf(buff, "my ip is:%s", ipaddr); }else{sprintf(buff, "%s", "my ip is:******"); }//有多个ip地址的时候,这样调用//IPInfo ips[10];//int len1 = 0;//GetLocalIPs(ips, 10,&len1);while(true){int nRet = recvfrom(sClient,buf,256,0,(struct sockaddr FAR *)&clientAddr,(int FAR *)&fromlength);if( SOCKET_ERROR != nRet ){char *pIPAddr = inet_ntoa(clientAddr.sin_addr);if( NULL != pIPAddr ){WCHAR wzIPBuffer[32] = {0};printf("clientAddr: %s\n", pIPAddr);printf("receive command: %s\n", buf);}if (strcmp(buf,GET_HOST_COMMAND) != 0){printf("the command not valid and was ignored.\n", buf);continue;}// 发送数据 int nSendSize = sendto(sClient, buff, strlen(buff), 0, (SOCKADDR*)&clientAddr, nAddrLen); if(SOCKET_ERROR == nSendSize) { int err = WSAGetLastError(); printf("\"sendto\" error!, error code is %d\n", err); return false; }}else{//AfxMessageBox(L"Recv UDP Failed");}Sleep(1000);}closesocket(sClient);return true;
}int main()
{if (!doServer()){printf("sever returned an error");return -1;}return 0;
}
- 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
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 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
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
注意上面是只有一个Ip地址的情况,有的机器可能会有多个IP地址,不同的网络,有线网,无线wifi等,需要获取多个ip地址的方法:
//结构体记录ip信息
typedef struct tagIPInfo
{ char ip[30];
}IPInfo; //获取多个ip地址信息列表
bool GetLocalIPs(IPInfo* ips,int maxCnt,int* cnt)
{ //1.初始化wsa WSADATA wsaData; int ret=WSAStartup(MAKEWORD(2,2),&wsaData); if (ret!=0) { return false; } //2.获取主机名 char hostname[256]; ret=gethostname(hostname,sizeof(hostname)); if (ret==SOCKET_ERROR) { return false; } //3.获取主机ip HOSTENT* host=gethostbyname(hostname); if (host==NULL) { return false; } //4.逐个转化为char*并拷贝返回 *cnt=host->h_length<maxCnt?host->h_length:maxCnt; for (int i=0;i<*cnt;i++) { in_addr* addr=(in_addr*)*host->h_addr_list; strcpy(ips[i].ip,inet_ntoa(addr[i])); } return true;
}
- 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
- 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
client端(windows控制台程序)
client端发送”GetIPAddr”命令,并及时接收client端发过来的信息
//#include "stdafx.h"
#include <WinSock2.h>
#include <stdio.h> #pragma comment(lib, "ws2_32.lib") const int MAX_BUF_LEN = 255; #define GET_HOST_COMMAND "GetIPAddr"
#define CLIENT_PORT 11121
#define SERVER_PORT 12811int main()
{ int nPort = SERVER_PORT;WORD wVersionRequested; WSADATA wsaData; int err; // 启动socket api wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { return -1; } if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { WSACleanup( ); return -1; } // 创建socket SOCKET connect_socket; connect_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if(INVALID_SOCKET == connect_socket) { err = WSAGetLastError(); printf("\"socket\" error! error code is %d\n", err); return -1; } // 用来绑定套接字 SOCKADDR_IN sin; sin.sin_family = AF_INET; sin.sin_port = htons(CLIENT_PORT); sin.sin_addr.s_addr = 0; // 用来从网络上的广播地址接收数据 SOCKADDR_IN sin_from; sin_from.sin_family = AF_INET; sin_from.sin_port = htons(nPort); sin_from.sin_addr.s_addr = INADDR_BROADCAST; //设置该套接字为广播类型, bool bOpt = true; setsockopt(connect_socket, SOL_SOCKET, SO_BROADCAST, (char*)&bOpt, sizeof(bOpt)); // 绑定套接字 err = bind(connect_socket, (SOCKADDR*)&sin, sizeof(SOCKADDR)); if(SOCKET_ERROR == err) {err = WSAGetLastError(); printf("\"bind\" error! error code is %d\n", err); return -1; } printf("the client is start.\n");int nAddrLen = sizeof(SOCKADDR); char buff[MAX_BUF_LEN] = ""; int nLoop = 0; char szMsg[]=GET_HOST_COMMAND;int nLen=sizeof(sin_from);if( SOCKET_ERROR==sendto(connect_socket, szMsg, strlen(szMsg), 0, (sockaddr*)&sin_from, nLen) ){// AfxMessageBox(L"Send UDP Failed"); return -1;}printf("send broadcast data:%s\n", GET_HOST_COMMAND);while(true) { // 接收数据 int nSendSize = recvfrom(connect_socket, buff, MAX_BUF_LEN, 0, (SOCKADDR*)&sin_from, &nAddrLen); if(SOCKET_ERROR == nSendSize) { err = WSAGetLastError(); printf("\"recvfrom\" error! error code is %d\n", err); return -1; } buff[nSendSize] = '\0'; printf("received ip: %s\n", buff); } return 0;
}
- 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
- 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
运行结果
- 1.Server端
- 2.Client端
运行结果说明:两个ip地址一样,是因为client和server我都运行在同一台机器上,如果有多台server,则client可以搜素到多个ip,受到条件限制,这里只有一个。
- 顶
- 0
- 踩
通过UDP广播获取网络中所有设备ip地址相关推荐
- windows C++ 通过UDP广播获取网络中所有设备ip地址
说明: 源码下载地址:http://download.csdn.net/detail/dxzysk/9756896 源码使用说明,先在需要获取IP地址的主机上运行server端程序,然后在需要搜索主机 ...
- 【电脑使用经验】怎么查看无线网络中电脑的IP地址?
1. 2. 3. 4. 5. 转载于:https://www.cnblogs.com/happykoukou/p/4437111.html
- 如何发现网络中的设备 设备发现协议(收集)
如何发现网络中的设备(收集) 如何发现网络中的设备(收集) 好吧,每次要SSH到树莓派都很麻烦,我是没找什么办法,每次都得连上显示器鼠标键盘.才能知道IP地址. 看了点python,写了个脚本来发出 ...
- 通过python基于netconf协议获取网络中网元的配置数据,助力企业网络控制自动化轻松实现!
摘要:在当今信息化时代,大多数企业都需要网络支撑企业的ICT运行,提升企业运行效率,针对企业网络中的网元设备(包括交换机,路由器,防火墙等),很多企业希望根据自身的业务特点定制网络管理,比如可以实现网 ...
- OSPF网络中两端设备网络类型不一致所带来的故障现象
[前言] 众所周知,两台运行OSPF的路由器如果将一端的网络类型保持广播类型不变,另一端的网络类型设置为P2P,那么两台路由器的邻居关系仍旧会建立(进入Full状态).然而这样的结果在一定程度上会使得 ...
- 网元——就是网络中的元素,网络中的设备。总之,网元是网络管理中可以监视和管理的最小单位...
网元 摘要: 网元由一个或多个机盘或机框组成, 能够独立完成一定的传输功能. 网管系统中的网元其实和这个差不多,简单理解就是网络中的元素,网络中的设备.总之,网元是网络管理中可以监视和管理的最 ...
- Linux 系统IP摄像头,linux内核模块获取设备IP地址
linux内核模块获取设备IP地址 发布时间:2008-08-04 21:07:54来源:红联作者:Shader 出自:http://blue8king.blog.163.com/blog/stati ...
- C# 网络编程之通过ip地址获取地理位置(补充)
前面我写过一篇文章"C# 网络编程之获取本机名.ip地址.域名.物理位置"里面可以根据输入的网址根据其ip地址获取器物理位置,其中该部分主要代码是通过有道网提供的在线第三方接口实现 ...
- 多级反向代理下,Java获取请求客户端的真实IP地址多中方法整合
在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实I ...
最新文章
- Eclipse小技巧
- 每个[NET]开发人员现在应该下载的十种必备工具
- arduino 机器视觉编程_万物皆可仿真的MATLAB/Simulink神奇在哪?解析如何将其应用于一整套机器人设计开发流程...
- extractCSS – 帮助你从 HTML 中快速分离出 CSS
- soapui工具_自动化测试需知的4项测试工具
- GDAL 2.0版本RPC校正速度测试
- linux主机慢的原因,51CTO博客-专业IT技术博客创作平台-技术成就梦想
- MVC源码解析 - UrlRoutingModule / 路由注册
- win10系统steam登陆计算机授权,steam登陆授权
- html和css设计网页实例,经典网页设计:30个创意的 CSS 应用案例
- DWG文件打开速度太慢怎么办!
- mui用ajax服务器交互,Mui --- app与服务器之间的交互原理、mui ajax使用
- pdf批量盖章软件_我的PDF休要乱用 超实用的PDF批量加水印神器 它来了
- Armbian搭建本地Gitea服务器
- EPMS System Analysis——AD验证、权限设计
- 服装行业如何用手持PDA盘点?
- FFMpeg ver 20160219-git-98a0053 滤镜中英文对照 2016.02.21 by 1CM
- 计算机调剂时科目不一样,考研调剂初试科目需要一样吗
- Joshua Porter谈优秀的UI设计原则
- EduCoder-Linux与Python编程2021(顺序与选择结构)
热门文章
- git commit -amend报错 ! [remote rejected] HEAD -> refs/for/master (duplicate request) error: failed to
- Firefox 使用、设置和常见问题的解决方法
- 计算机系的对联,首个计算机对联系统问世
- 虚拟化概述与虚拟化应用场景
- PWM脉宽调制信号转直流电压电流模拟信号输出隔离变送器5v10v4-20ma
- windows系统有线连接网络,再连入wify后,优先使用wify
- UI 相机和3D相机重叠显示
- Jetson TX2上配置archiconda、Yolov5、tensorrtx环境问题记录
- 解决win10环境下安装ArcGIS提示需要Microsoft.NET Framework 3.5sp1或等效环境问题
- Python 排序函数之“商品价格预算区间排序”