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