windows C++ 通过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;
}
注意上面是只有一个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;
}
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.Server端
- 2.Client端
运行结果说明:两个ip地址一样,是因为client和server我都运行在同一台机器上,如果有多台server,则client可以搜素到多个ip,受到条件限制,这里只有一个。
windows C++ 通过UDP广播获取网络中所有设备ip地址相关推荐
- 通过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
- 通过python基于netconf协议获取网络中网元的配置数据,助力企业网络控制自动化轻松实现!
摘要:在当今信息化时代,大多数企业都需要网络支撑企业的ICT运行,提升企业运行效率,针对企业网络中的网元设备(包括交换机,路由器,防火墙等),很多企业希望根据自身的业务特点定制网络管理,比如可以实现网 ...
- 如何发现网络中的设备 设备发现协议(收集)
如何发现网络中的设备(收集) 如何发现网络中的设备(收集) 好吧,每次要SSH到树莓派都很麻烦,我是没找什么办法,每次都得连上显示器鼠标键盘.才能知道IP地址. 看了点python,写了个脚本来发出 ...
- C# 网络编程之通过ip地址获取地理位置(补充)
前面我写过一篇文章"C# 网络编程之获取本机名.ip地址.域名.物理位置"里面可以根据输入的网址根据其ip地址获取器物理位置,其中该部分主要代码是通过有道网提供的在线第三方接口实现 ...
- 多级反向代理下,Java获取请求客户端的真实IP地址多中方法整合
在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实I ...
- OSPF网络中两端设备网络类型不一致所带来的故障现象
[前言] 众所周知,两台运行OSPF的路由器如果将一端的网络类型保持广播类型不变,另一端的网络类型设置为P2P,那么两台路由器的邻居关系仍旧会建立(进入Full状态).然而这样的结果在一定程度上会使得 ...
- 网元——就是网络中的元素,网络中的设备。总之,网元是网络管理中可以监视和管理的最小单位...
网元 摘要: 网元由一个或多个机盘或机框组成, 能够独立完成一定的传输功能. 网管系统中的网元其实和这个差不多,简单理解就是网络中的元素,网络中的设备.总之,网元是网络管理中可以监视和管理的最 ...
- linux 怎么设置静态ip,如何在Linux中设置静态IP地址和配置网络
如果您是Linux系统管理员,那么当您需要在系统上配置网络时,就会出现时间. 与可以使用动态IP地址的台式机不同,在服务器基础架构上,您需要设置静态IP地址(至少在大多数情况下).IP地址 :192. ...
最新文章
- 最好用的修改docker镜像源的方式
- android bootloader阶段GPIO的控制
- Linux系统入门学习:在Debian或Ubuntu上安装完整的内核源码
- java线程同步——条件对象+synchronized 关键字
- dom文档对象手册_HTML5学习之DOM编程
- 转 TCP中的序号和确认号
- dataframe 如何选中某列的一行_Spark中的RDD、DataFrame和DataSet讲解
- C语言爱心代码大全2022合集(可领)
- 2021美赛成绩查询入口和美赛成绩公布时间
- 微信小程序人脸识别java_微信小程序使用face++实现人脸识别登录注册
- YourTTS论文阅读
- 图像的频谱图简单理解
- 在IE/Chrome/Firefox等浏览器在线打开Word等Office文档完全解决方案
- macos安装更新错误_如何控制何时安装macOS更新
- Spark运行环境之SparkEnv和通信工具RpcEnv
- 痞子衡嵌入式:内存读写正确性压力测试程序(memtester)
- 实现html表单下划线可输入/css实现input只显示下划线
- openjudge 1.7.15 整理药名
- 【自学编程】C语言编程简单的小程序,计算长方体体积!
- 伪静态网站安全攻防如何理解
热门文章
- 游戏联运系统丨游戏联运系统防沉迷丨手游联运系统防沉迷丨游戏联运系统防沉迷的流程
- 计算机基础知识教程打印a4纸,学会这9个Word打印方法,不浪费任何一张A4纸,涨知识了...
- 《MATLAB智能算法30个案例》:第17章 基于PSO工具箱的函数寻优算法
- 男生学会计专业好还是学计算机专业,计算机专业 和 会计专业 相比 哪个更好学一点...
- 跑酷类小游戏开发(一)
- SiTime硅晶振解决方案--低轨卫星通信
- 软件工程作业-软件案例分析
- 数字藏品源码APP商城开发团队
- c++如何以回车作为循环结束的标志
- Python爬虫-爬取电影《星际穿越》评论并提取关键词