C ++でサーバーのイントラネットIPアドレスを取得する方法[Windows + Linux]

実際のプロジェクトアプリケーションでは、多くの場合、マシンのIPとポート番号をバインドする必要があります。または、サーバーとして、IP情報をデータベースに更新して、他のユーザーがデータベースにクエリを実行してアドレスを取得し、データを送信できるようにする必要があります。 。入れればマシンのIPをインテリジェントに取得できるので、コードの移植性が向上します。これは、WindowsとLinuxでローカルマシンのLANIPをインテリジェントに取得する方法です。何か問題がある場合はお知らせください。

(1)ウィンドウズ

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

プログラムは直接実行でき、2つのプラットフォームでテストおよび検証されています。

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

 

おすすめ

転載: blog.csdn.net/Swallow_he/article/details/88828803