En aplicaciones de proyectos reales, a menudo necesitamos vincular la IP y el número de puerto de la máquina, o como servidor, necesitamos actualizar nuestra información de IP en la base de datos, para que otros puedan consultar la base de datos para obtener la dirección y enviar datos. Si lo ponemos está hecho para obtener la IP de la máquina de forma inteligente, de forma que se mejore la portabilidad de nuestro código. Aquí hay una manera de obtener de forma inteligente la IP de LAN de nuestra máquina local en Windows y Linux: avísenos si hay algún problema.
(1) Ventanas
#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;
}
El programa se puede ejecutar directamente y ha sido probado y verificado en dos plataformas. ! !
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;
}