windows C++ 通過UDP廣播獲取網路中所有裝置ip地址[Win_CPP_Broadcast_GetIP]
windows C++ 通過UDP廣播獲取網路中所有裝置ip地址[Win_CPP_Broadcast_GetIP]
資料來源:https://www.itread01.com/content/1548632368.html
http://blog.csdn.net/dxzysk/article/details/55506450
https://download.csdn.net/detail/dxzysk/9756896
GITHUB: https://github.com/jash-git/Win_CPP_Broadcast_GetIP
SERVER
#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; }
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; }
圖