windows C++ 通過UDP廣播獲取網路中所有裝置ip地址[Win_CPP_Broadcast_GetIP]

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;   
} 


發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *