How to obtain the server's intranet IP address in C++ [Windows+Linux]

In actual project application, we often need to bind the IP and port number of the machine, or as a server, we need to update our IP information to the database, so that other ones can query the database to get the address and send data. If we put it It is made to obtain the IP of the machine intelligently, so that the portability of our code is improved. Here is a way to intelligently obtain the LAN IP of our local machine under windows and linux. Please advise us if there is something wrong.

(1)Windows

#include "winsock2.h"

#pragma comment(lib, "ws2_32.lib")

int GetLocalIP(char *ip)
{
	WSADATA wsaData;
	char name[155];
	PHOSTENT hostinfo;
	if (WSAStartup(MAKEWORD(2, 0), &wsaData) == 0)
	{
		if (gethostname(name, sizeof(name)) == 0)
		{
			if ((hostinfo = gethostbyname(name)) != NULL)
			{
				ip = inet_ntoa(*(struct in_addr *)*hostinfo->h_addr_list);
				printf("local ip : %s\n", ip);
			}
		}
		WSACleanup();
	}
	return 1;
}
int main(int argc, char argv[])
{
	char getip[64] = { 0 };
	GetLocalIP(getip);

	return 0;
}

(2)Linux

#include <stdio.h>   
#include <stdlib.h>   
#include <sys/types.h>   
#include <sys/socket.h>   
#include <netinet/in.h>   
#include <netdb.h>   
#include <arpa/inet.h>   
#include <signal.h>   
#include<string.h>   
#include <sys/ioctl.h>   
#include <linux/if.h>   

int GetLocalIP(char *ip)
{
	int  MAXINTERFACES = 16;
	int fd, intrface = 0;
	struct ifreq buf[MAXINTERFACES]; ///if.h   
	struct ifconf ifc; ///if.h   
	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) //socket.h   
	{
		ifc.ifc_len = sizeof buf;
		ifc.ifc_buf = (caddr_t)buf;
		if (!ioctl(fd, SIOCGIFCONF, (char *)&ifc)) //ioctl.h   
		{
			intrface = ifc.ifc_len / sizeof (struct ifreq);
			while (intrface-- > 0)
			{
				if (!(ioctl(fd, SIOCGIFADDR, (char *)&buf[intrface])))
				{
					sprintf(ip, "%s", inet_ntoa(((struct sockaddr_in*)(&buf[intrface].ifr_addr))->sin_addr));
					printf("ip:%s\n", ip);
					break;
				}

			}
		}
		close(fd);
	}
	return 0;
}

The program can be run directly and has been tested and verified on two platforms! ! !

const char * GetLocalAddr(char *ifaddr, size_t ifaddr_size)
{
	char *ifaddr_data = NULL;
#ifdef WIN32
	char     hostname[155];
	PHOSTENT hostinfo;
	if (gethostname(hostname, sizeof(hostname)) == 0)
	{
		if ((hostinfo = gethostbyname(hostname)) != NULL)
		{
			ifaddr_data = strncpy(ifaddr, inet_ntoa(*(struct in_addr *)*hostinfo->h_addr_list), ifaddr_size);
		}
	}
#else
	int  MAXINTERFACES = 16;
	int fd, intrface = 0;
	struct ifreq  buf[MAXINTERFACES]; ///if.h   
	struct ifconf ifc; ///if.h   
	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) //socket.h   
	{
		ifc.ifc_len = sizeof(buf);
		ifc.ifc_buf = (caddr_t)buf;
		if (!ioctl(fd, SIOCGIFCONF, (char *)&ifc)) //ioctl.h   
		{
			intrface = ifc.ifc_len / sizeof(struct ifreq);
			for (int i = 0; i < intrface; i++)
			{
				struct ifreq * lp_ifc_req = &buf[i];

				char    if_name[32] = { 0 };
				strncpy(if_name, lp_ifc_req->ifr_name, sizeof(if_name));

				int     if_flag     = 0;
				ioctl(fd, SIOCGIFFLAGS, lp_ifc_req);
				if_flag = lp_ifc_req->ifr_flags;

				char    if_addr[32] = { 0 };
				ioctl(fd, SIOCGIFADDR, lp_ifc_req);
				inet_ntop(AF_INET, &(((struct sockaddr_in *)&(lp_ifc_req->ifr_addr))->sin_addr),
					if_addr, sizeof(if_addr));
#if 1
				printf("%2d: ifr_name=%s, ifr_flags= 0x%x, ifr_addr= %s\n", i, if_name, if_flag,
					if_addr);
#endif

#define  IFF_NET_RUNNING (IFF_UP | IFF_BROADCAST | IFF_MULTICAST | IFF_RUNNING)
				if ((if_flag & IFF_LOOPBACK) == (IFF_LOOPBACK) || (if_flag & IFF_NET_RUNNING) != IFF_NET_RUNNING)
					continue;
				ifaddr_data = strncpy(ifaddr, if_addr, ifaddr_size);
				break;
			}
		}
		close(fd);
	}
#endif // WIN32

	return ifaddr_data;
}

 

Guess you like

Origin blog.csdn.net/Swallow_he/article/details/88828803