Written in the beginning
In the latest TCP connection to the device, the project of device input stream processing and device operation control was used to communicate through wifi LAN. At that time, the gateway address of wifi was used as the IP address of the device. When I consulted the data, I found that the replies on the Internet were all the same version. The author tried this version in person and had a great chance to get the IP of cellular mobile data when the APP allowed both wireless LAN and cellular data to be opened. It’s a headache, because the product will not accept the normal operation under the condition of only using wireless LAN when the APP is opened. After several twists and turns, the problem was finally solved and recorded in this article. Have the same situation can be discussed.
Versions of risky code
* * * * access gateway + (nsstrings *) getGatewayIpForCurrentWiFi {nsstrings * address = @ "error"; struct ifaddrs *interfaces = NULL; struct ifaddrs *temp_addr = NULL; int success = 0; // retrieve the current interfaces - returns 0 on success success = getifaddrs(&interfaces); if (success == 0) { // Loop through linked list of interfaces temp_addr = interfaces; //*/ while(temp_addr ! = NULL) { /*/ int i=255; while((i--)>0) //*/ if(temp_addr->ifa_addr->sa_family == AF_INET) { // Check if interface is en0 which is the wifi connection on the iPhone if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]){ // Get NSString from C String //ifa_addr //ifa->ifa_dstaddr is the broadcast address, which explains the "255's" // address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_dstaddr)->sin_addr)]; address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)]; / / routerIP - 192.168.1.255 broadcast address NSLog (@ "broadcast address - % @", [nsstrings stringWithUTF8String: inet_ntoa (((struct sockaddr_in *)temp_addr->ifa_dstaddr)->sin_addr)]); / / - 192.168.1.106 native address NSLog (@ "local device IP - % @", [nsstrings stringWithUTF8String: inet_ntoa (((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)]); / / - 255.255.255.0 subnet mask address NSLog (@ "netmask - % @", [nsstrings stringWithUTF8String: inet_ntoa (((struct sockaddr_in *)temp_addr->ifa_netmask)->sin_addr)]); / / - en0 port address NSLog (@ "interface - % @", [nsstrings stringWithUTF8String: temp_addr - > ifa_name]); in_addr_t i = inet_addr([address cStringUsingEncoding:NSUTF8StringEncoding]); in_addr_t* x = &i; unsigned char *s = getdefaultgateway(x); NSString *ip=[NSString stringWithFormat:@"%d.%d.%d.%d",s[0],s[1],s[2],s[3]]; free(s); return ip; } } temp_addr = temp_addr->ifa_next; } } // Free memory freeifaddrs(interfaces); Return @ "0.0.0.0"; }Copy the code
Where getDefaultgateway in c file getgateway.c code is as follows:
unsigned char * getdefaultgateway(in_addr_t * addr) { unsigned char * octet=malloc(4); # if 0 / * net. The route. 0. Inet. Dump. 0.0? */ int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_DUMP, 0, 0/*tableid*/}; #endif /* net.route.0.inet.flags.gateway */ int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_GATEWAY}; size_t l; char * buf, * p; struct rt_msghdr * rt; struct sockaddr * sa; struct sockaddr * sa_tab[RTAX_MAX]; int i; if(sysctl(mib, sizeof(mib)/sizeof(int), 0, &l, 0, 0) < 0) { return octet; } if(l>0) { buf = malloc(l); if(sysctl(mib, sizeof(mib)/sizeof(int), buf, &l, 0, 0) < 0) { return octet; } for(p=buf; p<buf+l; p+=rt->rtm_msglen) { rt = (struct rt_msghdr *)p; sa = (struct sockaddr *)(rt + 1); for(i=0; i<RTAX_MAX; i++) { if(rt->rtm_addrs & (1 << i)) { sa_tab[i] = sa; sa = (struct sockaddr *)((char *)sa + ROUNDUP(sa->sa_len)); } else { sa_tab[i] = NULL; } } if( ((rt->rtm_addrs & (RTA_DST|RTA_GATEWAY)) == (RTA_DST|RTA_GATEWAY)) && sa_tab[RTAX_DST]->sa_family == AF_INET && sa_tab[RTAX_GATEWAY]->sa_family == AF_INET) { for (int i=0; i<4; i++){ octet[i] = ( ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr >> (i*8) ) & 0xFF; } } } free(buf); } return octet; }Copy the code
A perfectly streamlined version of the solution
+ (NSString *)getGatewayIP {
NSString *ipString = nil;
struct in_addr gatewayaddr;
int r = getdefaultgateway(&(gatewayaddr.s_addr));
if(r >= 0) {
ipString = [NSString stringWithFormat: @"%s",inet_ntoa(gatewayaddr)];
} else {
NSLog(@"Wifi is not connected or you are using simulator Gateway ip address will be nil");
}
return ipString;
}
Copy the code
Where getDefaultgateway in c file getgateway.c code same.