通过UDP广播获取网络中所有设备ip地址
2017-08-30 12:31
423 查看
说明:
源码下载地址:http://download.csdn.net/detail/dxzysk/9756896
源码使用说明,先在需要获取IP地址的主机上运行server端程序,然后在需要搜索主机的Pc上运行client端程序
本文是windows版,VC++,在VS2010环境下调试成功。有时候需要搜索网络中的设备,机器,服务器等,这就要要用到UDP广播的方式,发送广播命令,广播给网络中的每一个主机,该主机或设备接收到广播命令后,立刻发送给请求端自己的设备信息,这里以IP信息为例子。
思路
在每一个设备中部署sever端程序进行监控,client端发送广播命令,每一个server收到命令后,返回给client自己的ip地址信息,给出代码如下,其中,有部分,比如获取ip地址参考来自网络,尊重原创,乐于分享。
server端监听广播命令”GetIPAddr”,收到命令后就相应
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地址的方法:
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端发送”GetIPAddr”命令,并及时接收client端发过来的信息
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
踩
源码下载地址: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.0 WORD 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 12811 int 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
踩
相关文章推荐
- QT 通过UDP广播获取网络中所有设备ip地址
- windows C++ 通过UDP广播获取网络中所有设备ip地址
- windows C++ 通过UDP广播获取网络中所有设备ip地址
- QT 通过UDP广播获取网络中所有设备信息
- 同wifi环境下android设备自动获取socket服务端的ip地址和端口号的方法-UDP广播
- 通过UDP广播自动获取IP地址
- iOS 怎样通过UDP发送广播寻找设备,拿到ip地址,然后用TCP 连接设备
- Atitit 网络设备的自动发现机制 需求如下: 1、自动获取当前设备所在网段及当前与当前网段有连接的网段的所有IP,并判断出是哪类设备。如:服务器、交换机、防火墙等。 2、如何根据第1点得到的
- ios下获取所有实体/虚拟网卡的信息,并以此判断设备所处的网络状态
- iOS 获取设备所连网络的IP地址
- C#获取本机上所有网络接口及真实IP地址信息
- C# 网络编程之通过ip地址获取地理位置(补充)
- Python 网络爬虫 009 (编程) 通过正则表达式来获取一个网页中的所有的URL链接,并下载这些URL链接的源代码
- 通过Python在windows和linux中获取当前网络IP地址的一些方法
- openwrt dnsmasq启动问题偶尔导致lan侧设备无法通过dhcp获取IP地址
- Python 网络爬虫 009 (编程) 通过正则表达式来获取一个网页中的所有的URL链接,并下载这些URL链接的源代码
- 通过Socket configuration controls 获取网络设备地址
- 通过IP地址获取局域网中设备的MAC地址——java实现
- 运行中修改协调器PAN ID和Channel,协调器广播至所有的设备重启加入新建后的网络
- C#获取本机上所有网络接口及真实IP地址信息