获取IOS设备当前地址,已验证使用通过

本文详细介绍了如何使用C语言通过网络接口获取设备的当前IP地址,包括代码实现、注意事项及优化建议,适合对网络编程感兴趣的开发者阅读。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目需要获取设备的当前地址,为此google了一下,找到不少文章。
主流的方法都是用c语言的方式读网卡地址,这里实践的过程中,发现并不能直接应用。
我把实践和调试的过程进行总结,更便于其他同学的使用。
目前的方法(这个一搜一大堆,都一样的):
如:http://blog.youkuaiyun.com/devday/article/details/6858330
这个是.c文件的内容,文件名为定位IpCore.c,从网上找到后做了一些修改。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/sockio.h>
#include <net/if.h>
#include <errno.h>
#include <net/if_dl.h>
#include <net/ethernet.h>


//#include "GetAddresses.h"


#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))


#define BUFFERSIZE 4000
#define MAXADDRS 32


char *if_names[MAXADDRS];
char *ip_names[MAXADDRS];
char *hw_addrs[MAXADDRS];
unsigned long ip_addrs[MAXADDRS];


static int nextAddr = 0;


void InitAddresses()
{
int i;
for (i=0; i<MAXADDRS; ++i)
{
if_names[i] = ip_names[i] = hw_addrs[i] = NULL;
ip_addrs[i] = 0;
}
}


void FreeAddresses()
{
int i;
for (i=0; i<MAXADDRS; ++i)
{
if (if_names[i] != 0) free(if_names[i]);
if (ip_names[i] != 0) free(ip_names[i]);
if (hw_addrs[i] != 0) free(hw_addrs[i]);
ip_addrs[i] = 0;
}
InitAddresses();
}


void GetIPAddresses()
{
int i, len, flags;
char buffer[BUFFERSIZE], *ptr, lastname[IFNAMSIZ], *cptr;
struct ifconf ifc;
struct ifreq *ifr, ifrcopy;
struct sockaddr_in *sin;


char temp[80];


int sockfd;


for (i=0; i<MAXADDRS; ++i)
{
if_names[i] = ip_names[i] = NULL;
ip_addrs[i] = 0;
}


sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
{
perror("socket failed");
return;
}


ifc.ifc_len = BUFFERSIZE;
ifc.ifc_buf = buffer;


if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0)
{
perror("ioctl error");
return;
}


lastname[0] = 0;


for (ptr = buffer; ptr < buffer + ifc.ifc_len; )
{
ifr = (struct ifreq *)ptr;
len = max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len);
ptr += sizeof(ifr->ifr_name) + len; // for next one in buffer


if (ifr->ifr_addr.sa_family != AF_INET)
{
continue; // ignore if not desired address family
}


if ((cptr = (char *)strchr(ifr->ifr_name, ':')) != NULL)
{
*cptr = 0; // replace colon will null
}


if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0)
{
continue; /* already processed this interface */
}


memcpy(lastname, ifr->ifr_name, IFNAMSIZ);


ifrcopy = *ifr;
ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy);
flags = ifrcopy.ifr_flags;
if ((flags & IFF_UP) == 0)
{
continue; // ignore if interface not up
}


if_names[nextAddr] = (char *)malloc(strlen(ifr->ifr_name)+1);
if (if_names[nextAddr] == NULL)
{
return;
}
strcpy(if_names[nextAddr], ifr->ifr_name);


sin = (struct sockaddr_in *)&ifr->ifr_addr;
strcpy(temp, inet_ntoa(sin->sin_addr));


ip_names[nextAddr] = (char *)malloc(strlen(temp)+1);
if (ip_names[nextAddr] == NULL)
{
return;
}
strcpy(ip_names[nextAddr], temp);


ip_addrs[nextAddr] = sin->sin_addr.s_addr;


++nextAddr;
}


close(sockfd);
}


void GetHWAddresses()
{
struct ifconf ifc;
struct ifreq *ifr;
int i, sockfd;
char buffer[BUFFERSIZE], *cp, *cplim;
char temp[80];


for (i=0; i<MAXADDRS; ++i)
{
hw_addrs[i] = NULL;
}


sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
{
perror("socket failed");
return;
}


ifc.ifc_len = BUFFERSIZE;
ifc.ifc_buf = buffer;


if (ioctl(sockfd, SIOCGIFCONF, (char *)&ifc) < 0)
{
perror("ioctl error");
close(sockfd);
return;
}


ifr = ifc.ifc_req;


cplim = buffer + ifc.ifc_len;


for (cp=buffer; cp < cplim; )
{
ifr = (struct ifreq *)cp;
if (ifr->ifr_addr.sa_family == AF_LINK)
{
struct sockaddr_dl *sdl = (struct sockaddr_dl *)&ifr->ifr_addr;
int a,b,c,d,e,f;
int i;


strcpy(temp, (char *)ether_ntoa((const struct ether_addr *)(LLADDR(sdl))));
sscanf(temp, "%x:%x:%x:%x:%x:%x", &a, &b, &c, &d, &e, &f);
sprintf(temp, "%02X:%02X:%02X:%02X:%02X:%02X",a,b,c,d,e,f);


for (i=0; i<MAXADDRS; ++i)
{
if ((if_names[i] != NULL) && (strcmp(ifr->ifr_name, if_names[i]) == 0))
{
if (hw_addrs[i] == NULL)
{
hw_addrs[i] = (char *)malloc(strlen(temp)+1);
strcpy(hw_addrs[i], temp);
break;
}
}
}
}
cp += sizeof(ifr->ifr_name) + max(sizeof(ifr->ifr_addr), ifr->ifr_addr.sa_len);
}


close(sockfd);
}


//获取设备ip
char* GetIp()
{
InitAddresses();
GetIPAddresses();
char *ip = "";
if (sizeof(ip_names)/sizeof(ip_names[0]) > 2) {
ip = ip_names[1];
}
return ip;
}


修改的地方有几处:
1、很多地方没有定义MAXADDRS这个值。
#define MAXADDRS 32

2、加了一个函数

char* GetIp()

3、修复警告错误Implicit declaration of function 'ether_ntoa' is invalid in C99。
#include <net/ethernet.h>
struct sockaddr_dl *sdl = (struct sockaddr_dl *)&ifr->ifr_addr;
链接: http://stackoverflow.com/questions/11245280/implicit-declaration-of-function-ether-ntoa-is-invalid-in-c99


具体用法:OC要和C进行混合编译,不能直接在.m中#import "IpCore.c",需要为.c文件写一个.h文件,并预定义这些函数:
IpCore.h的文件内容如下:
#ifndef sngAssist_IpCore_h
#define sngAssist_IpCore_h
//预定义函数
void InitAddresses();
void FreeAddresses();
void GetIPAddresses();
void GetHWAddresses();
char* GetIp();
#endif

然后要使用这些函数的地方:

#import "IpCore.h"
NSString *ip = [NSString stringWithFormat:@"%s", GetIp()];


这样就可以拿到IP了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值