iOS 获取链接的Wifi的IP、名字,检测是否连接到WLAN

//

//  UIDevice-Reachability.h

//  testSearchVC

//

//  Created by mifit on 15/9/1.

//  Copyright (c) 2015 mifit. All rights reserved.

//


#import <UIKit/UIKit.h>


@interface UIDevice(Reachability)

/// 本机名字

+ (NSString *) hostname;

/// 连接的wifi名字

+ (NSString *) wifiName;

/// 连接的WiFi ip

+ (NSString *) localWiFiIPAddress;

/// 是否连接到WLAN

+ (BOOL) activeWLAN;


@end


//

//  UIDevice-Reachability.m

//  testSearchVC

//

//  Created by mifit on 15/9/1.

//  Copyright (c) 2015 mifit. All rights reserved.

//

#include <unistd.h>

#include <sys/sysctl.h>

#include <arpa/inet.h>

#include <netdb.h>

#include <net/if.h>

#include <net/if_dl.h>

#include <netinet/in.h>

#include <ifaddrs.h>

#import <SystemConfiguration/CaptiveNetwork.h>

#import "wwanconnect.h"


#import "UIDevice-Reachability.h"


@implementation UIDevice(Reachability)

+ (NSString *)wifiName{

    NSString *wifiName = nil;

    CFArrayRef wifiInterfaces =CNCopySupportedInterfaces();

    

    if (!wifiInterfaces) {

        return nil;

    }

    

    NSArray *interfaces = (__bridgeNSArray *)wifiInterfaces;

    

    for (NSString *interfaceNamein interfaces) {

        CFDictionaryRef dictRef =CNCopyCurrentNetworkInfo((__bridgeCFStringRef)(interfaceName));

        

        if (dictRef) {

            NSDictionary *networkInfo = (__bridgeNSDictionary *)dictRef;

            wifiName = [networkInfo objectForKey:(__bridgeNSString *)kCNNetworkInfoKeySSID];

            

            CFRelease(dictRef);

        }

    }

    

    CFRelease(wifiInterfaces);

    return wifiName;

}


+ (NSString *) hostname{

    char baseHostName[255];

    int success = gethostname(baseHostName, 255);

    if (success != 0) return nil;

    baseHostName[255] = '\0';

    

#if !TARGET_IPHONE_SIMULATOR

    return [NSStringstringWithFormat:@"%s.local", baseHostName];

#else

    return [NSString stringWithFormat:@"%s", baseHostName];

#endif

}


// Direct from Apple. Thank you Apple

+ (BOOL)addressFromString:(NSString *)IPAddress address:(structsockaddr_in *)address{

    if (!IPAddress || ![IPAddress length]) {

        return NO;

    }

    

    memset((char *) address,sizeof(structsockaddr_in), 0);

    address->sin_family = AF_INET;

    address->sin_len = sizeof(struct sockaddr_in);

    

    int conversionResult = inet_aton([IPAddress UTF8String], &address->sin_addr);

    if (conversionResult == 0) {

        NSAssert1(conversionResult !=1, @"Failed to convert the IP address string into a sockaddr_in: %@", IPAddress);

        return NO;

    }

    

    return YES;

}


+ (NSString *) getIPAddressForHost: (NSString *) theHost{

    structhostent *host = gethostbyname([theHostUTF8String]);

    

    if (host == NULL) {

        herror("resolv");

        return NULL;

    }

    

    struct in_addr **list = (structin_addr **)host->h_addr_list;

    NSString *addressString = [NSStringstringWithCString:inet_ntoa(*list[0])];

    return addressString;

}


#if ! defined(IFT_ETHER)

#define IFT_ETHER 0x6   // Ethernet CSMACD

#endif


// Matt Brown's get WiFi IP addy solution

// Author gave permission to use in Cookbook under cookbook license

// http://mattbsoftware.blogspot.com/2009/04/how-to-get-ip-address-of-iphone-os-v221.html

+ (NSString *) localWiFiIPAddress{

    BOOL success;

    struct ifaddrs * addrs;

    const structifaddrs * cursor;

    

    success = getifaddrs(&addrs) == 0;

    if (success) {

        cursor = addrs;

        while (cursor != NULL) {

            // the second test keeps from picking up the loopback address

            if (cursor->ifa_addr->sa_family ==AF_INET && (cursor->ifa_flags &IFF_LOOPBACK) == 0)

            {

                NSString *name = [NSStringstringWithUTF8String:cursor->ifa_name];

                if ([name isEqualToString:@"en0"]) { // found the WiFi adapter

                    return [NSStringstringWithUTF8String:inet_ntoa(((structsockaddr_in *)cursor->ifa_addr)->sin_addr)];

                }

            }

            cursor = cursor->ifa_next;

        }

        freeifaddrs(addrs);

    }

    return nil;

}


// Return the local IP address

+ (NSString *) localIPAddress{

    structhostent *host = gethostbyname([[selfhostname] UTF8String]);

    if (host == NULL)

    {

        herror("resolv");

        return nil;

    }

    else {

        struct in_addr **list = (structin_addr **)host->h_addr_list;

        return [NSStringstringWithCString:inet_ntoa(*list[0])];

    }

    return nil;

}


+ (NSString *) whatismyipdotcom{

    NSError *error;

    NSURL *ipURL = [NSURLURLWithString:@"http://www.whatismyip.com/automation/n09230945.asp"];

    NSString *ip = [NSStringstringWithContentsOfURL:ipURL encoding:1error:&error];

    if (!ip) return [errorlocalizedDescription];

    return ip;

}


+ (BOOL) activeWLAN{

    return ([selflocalWiFiIPAddress] != nil);

}


#pragma mark Forcing WWAN connection


MyStreamInfoPtr myInfoPtr;


static void myClientCallback(void *refCon){

    int  *val = (int*)refCon;

    printf("myClientCallback entered - value from refCon is %d\n", *val);

}


+ (void) forceWWAN{

    int value = 0;

    myInfoPtr = (MyStreamInfoPtr)StartWWAN(myClientCallback, &value);

    if (myInfoPtr)

    {

        printf("Started WWAN\n");

    }

    else

    {

        printf("Failed to start WWAN\n");

    }

}


+ (void) shutdownWWAN{

    if (myInfoPtr)StopWWAN((MyInfoRef)myInfoPtr);

}

@end


--------------------另外需要的两个文件源码 --------------------

//

//  wwanconnect.h

//  testSearchVC

//

//  Created by mifit on 15/9/1.

//  Copyright (c) 2015 mifit. All rights reserved.

//


// Direct from Apple. Thank you Apple

// Direct from Apple. Thank you Apple


#if !defined(__WWAN_CONNECT__)

#define __WWAN_CONNECT__    1


#include <CoreFoundation/CoreFoundation.h>

#include <assert.h>


#define kTestHost   "www.whatismyip.com"

#define kTestPort   80


typedef void (*ConnectClientCallBack)(void *refCon);



struct MyStreamInfoStruct{

    CFWriteStreamRefwStreamRef;

    CFReadStreamRefrStreamRef;

    ConnectClientCallBackclientCB;

    void *refCon;

    CFStreamErrorerror;

    Boolean errorOccurred;

    Boolean isConnected;

    Boolean isStreamInitd;

    Boolean isClientSet;

};


typedef structMyStreamInfoStruct MyStreamInfo;

typedef structMyStreamInfoStruct *MyStreamInfoPtr;

typedef struct__MyInfoRef *MyInfoRef;


/*

 *  StartWWAN()

 *

 *  Discussion:

 *    This function will initiate a Wireless Wide Area Network (WWAN)

 *     connection by using the CFSocketStream API to connect with a

 *     server system defined by kTestHost:kTestPort above.

 *     No communications are expected to happen over the CFSocketStream

 *     connection.

 *

 *    clientCB:

 *     if the connection is opened, the callback routine, if not NULL

 *     will be called. function defintion - see ConnectClientCallBack above

 *

 *    refCon:

 *     if a client callback, clientCB is defined, then the refCon

 *      parameter will be the argument to the client callback

 *

 *    return:

 *     if the WWAN connection is successful, a MyInfoRef value is returned

 *     The MyInfoRef value must be passed to StopWWAN to stop the WWAN

 *     connection.

 *     A NULL result indicates that the connection was unsuccessful

 *

 */

extern MyInfoRef StartWWAN(ConnectClientCallBack clientCB,void *refCon);


/*

 *  StopWWAN()

 *

 *  Discussion:

 *    This function closes the CFSocketStream which was used to establish the

 *    WWAN connection. Once the WWAN connection has been started, BSD

 *    network functions can be used to communicate across the WWAN connection.

 *    As of the writing of this sample, there is no guarantee that the use of

 *    only BSD socket API's will maintain the WWAN connection.

 *

 *    infoRef:

 *     pass in the MyInfoRef result from the StartWWAN function.

 *

 */


extern void StopWWAN(MyInfoRef infoRef);


#endif // __WWAN_CONNECT__




// Direct from Apple. Thank you Apple


#include "wwanconnect.h"

#include <CFNetwork/CFSocketStream.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <unistd.h>

#include <ifaddrs.h>

#include <stdio.h>


static Boolean TestGetIFAddrs(void);

static void MyCFWriteStreamClientCallBack(CFWriteStreamRef stream,CFStreamEventType type, void *clientCallBackInfo);

static void CleanupAfterWAAN(MyStreamInfoPtr myInfoPtr);

static void CloseStreams(MyStreamInfoPtr myInfoPtr);


static Boolean TestGetIFAddrs(void)

{

    int result;

    struct  ifaddrs*ifbase, *ifiterator;

    int done =0;

    Boolean addrFound = FALSE;

    char loopbackname[] = "lo0/0";

    

    result = getifaddrs(&ifbase);

    ifiterator = ifbase;

    while (!done && (ifiterator != NULL))

    {

        if (ifiterator->ifa_addr->sa_family ==AF_INET)

        {

            if (memcmp(ifiterator->ifa_name, loopbackname,3))

            {

                structsockaddr *saddr, *netmask, *daddr;

                saddr = ifiterator->ifa_addr;

                netmask = ifiterator->ifa_netmask;

                daddr = ifiterator->ifa_dstaddr;

                

                // we've found an entry for the IP address

                struct sockaddr_in *iaddr;

                charaddrstr[64];

                iaddr = (struct sockaddr_in *)saddr;

                inet_ntop(saddr->sa_family, &iaddr->sin_addr, addrstr,sizeof(addrstr));

                fprintf(stderr,"ipv4 interface name %s, source IP addr %s ", ifiterator->ifa_name, addrstr);

                

                iaddr = (struct sockaddr_in *)netmask;

                if (iaddr)

                {

                    inet_ntop(saddr->sa_family, &iaddr->sin_addr, addrstr,sizeof(addrstr));

                    fprintf(stderr,"netmask IP addr %s ", addrstr);

                }

                

                iaddr = (struct sockaddr_in *)daddr;

                if (iaddr)

                {

                    inet_ntop(saddr->sa_family, &iaddr->sin_addr, addrstr,sizeof(addrstr));

                    fprintf(stderr,"dest/broadcast IP addr %s.\n\n", addrstr);

                }

                return TRUE;

            }

            

        }

        else if (ifiterator->ifa_addr->sa_family ==AF_INET6)

        {

            // we've found an entry for the IP address

            struct sockaddr_in6 *iaddr6 = (structsockaddr_in6 *)ifiterator->ifa_addr;

            charaddrstr[256];

            inet_ntop(ifiterator->ifa_addr->sa_family, iaddr6, addrstr,sizeof(addrstr));

            fprintf(stderr,"ipv6 interface name %s, source IP addr %s \n\n", ifiterator->ifa_name, addrstr);

        }

        ifiterator = ifiterator->ifa_next;

    }

    if (ifbase)

        freeifaddrs(ifbase);/* done with the memory allocated by getifaddrs */

    

    return addrFound;

}


static void MyCFWriteStreamClientCallBack(CFWriteStreamRef stream,CFStreamEventType type, void *clientCallBackInfo)

{

    MyStreamInfoPtrmyInfoPtr = (MyStreamInfoPtr) clientCallBackInfo;

    

    printf("MyCFWriteStreamClientCallBack entered - event is %lu \n", type);

    

    switch (type)

    {

        casekCFStreamEventOpenCompleted:

            myInfoPtr->isConnected = TRUE;

            TestGetIFAddrs();// call the test function to return the local ip address associated with this connection.

            if (myInfoPtr->clientCB)

            {

                // call client callback routine

                myInfoPtr->clientCB(myInfoPtr->refCon);

            }

            printf("write stream connected\n");

            break;

            

        casekCFStreamEventErrorOccurred:

            myInfoPtr->errorOccurred = TRUE;

            myInfoPtr->error = CFWriteStreamGetError(myInfoPtr->wStreamRef);

            printf("write stream error %d .. giving up\n", myInfoPtr->error.error);

            break;

            

        default:

            printf("event type %lu occurred\n",type);

            break;

    }

    // stop the run loop at this point

    CFRunLoopStop(CFRunLoopGetCurrent());

}


extern MyInfoRef StartWWAN(ConnectClientCallBack clientCB,void *refCon)

{

    char host[] = kTestHost;

    int portNum =kTestPort;

    CFDataRef addressData;

    MyStreamInfoPtrmyInfoPtr;

    CFStreamClientContextctxt = {0, NULL, NULL, NULL, NULL};

    Boolean errorOccurred = FALSE;

    

    myInfoPtr = malloc(sizeof(MyStreamInfo));

    if (!myInfoPtr)

    {

        return NULL;

    }

    

    // init the allocated memory

    memset(myInfoPtr, 0, sizeof(MyStreamInfo));

    myInfoPtr->clientCB = clientCB;

    myInfoPtr->refCon = refCon;

    ctxt.info = myInfoPtr;

    

    // Check for a dotted-quad address, if so skip any host lookups

    in_addr_t addr = inet_addr(host);

    if (addr != INADDR_NONE) {

        // Create the streams from numberical host

        struct sockaddr_in sin;

        memset(&sin, 0, sizeof(sin));

        

        sin.sin_len= sizeof(sin);

        sin.sin_family = AF_INET;

        sin.sin_addr.s_addr = addr;

        sin.sin_port = htons(portNum);

        

        addressData = CFDataCreate(NULL, (UInt8 *)&sin,sizeof(sin));

        CFSocketSignature sig = { AF_INET, SOCK_STREAM, IPPROTO_TCP, addressData };

        

        // Create the streams.

        CFStreamCreatePairWithPeerSocketSignature(kCFAllocatorDefault, &sig, &(myInfoPtr->rStreamRef), &(myInfoPtr->wStreamRef));

        CFRelease(addressData);

    } else {

        // Create the streams from ascii host name

        CFStringRef hostStr =CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, host,kCFStringEncodingUTF8, kCFAllocatorNull);

        CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, hostStr, portNum, &(myInfoPtr->rStreamRef), &(myInfoPtr->wStreamRef));

    }

    

    myInfoPtr->isConnected = FALSE;

    myInfoPtr->isStreamInitd = TRUE;

    myInfoPtr->isClientSet = FALSE;

    

    // Inform the streams to kill the socket when it is done with it.

    // This effects the write stream too since the pair shares the

    // one socket.

    CFWriteStreamSetProperty(myInfoPtr->wStreamRef,kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);

    

    // set up the client

    if (!CFWriteStreamSetClient(myInfoPtr->wStreamRef,kCFStreamEventOpenCompleted | kCFStreamEventErrorOccurred |kCFStreamEventEndEncountered,

                                MyCFWriteStreamClientCallBack, &ctxt))

    {

        printf("CFWriteStreamSetClient failed\n");

        errorOccurred = TRUE;

    }

    else

        myInfoPtr->isClientSet = TRUE;

    

    if (!errorOccurred)

    {

        // schedule the stream

        CFWriteStreamScheduleWithRunLoop(myInfoPtr->wStreamRef,CFRunLoopGetCurrent(), kCFRunLoopCommonModes);

        

        // Try to open the stream.

        if (!CFWriteStreamOpen(myInfoPtr->wStreamRef))

        {

            printf("CFWriteStreamOpen failed\n");

            errorOccurred = TRUE;

        }

    }

    

    if (!errorOccurred)

    {

        // everything worked so far, so run the runloop - when the callback gets called, it will stop the run loop

        printf("CFWriteStreamOpen returned with no error - calling CFRunLoopRun\n");

        CFRunLoopRun();

        if (myInfoPtr->errorOccurred)

            errorOccurred = TRUE;

        printf("after CFRunLoopRun - returning\n");

    }

    

    if (errorOccurred)

    {

        myInfoPtr->isConnected = FALSE;

        CleanupAfterWAAN(myInfoPtr);

        CloseStreams(myInfoPtr);

        

        if (myInfoPtr->isStreamInitd)

        {

            CFRelease(myInfoPtr->rStreamRef);

            CFRelease(myInfoPtr->wStreamRef);

            myInfoPtr->isStreamInitd = FALSE;

        }

        free(myInfoPtr);

        return NULL;

    }

    return (MyInfoRef)myInfoPtr;

}


static void CleanupAfterWAAN(MyStreamInfoPtr myInfoPtr)

{

    assert(myInfoPtr != NULL);

    if (myInfoPtr->isClientSet)

    {

        CFWriteStreamSetClient(myInfoPtr->wStreamRef,0, NULL, NULL);

        CFWriteStreamUnscheduleFromRunLoop(myInfoPtr->wStreamRef,CFRunLoopGetCurrent(), kCFRunLoopCommonModes);

        myInfoPtr->isClientSet = FALSE;

    }

}


static void CloseStreams(MyStreamInfoPtr myInfoPtr)

{

    assert(myInfoPtr != NULL);

    if (myInfoPtr->rStreamRef)

    {

        CFReadStreamClose(myInfoPtr->rStreamRef);

        myInfoPtr->rStreamRef = NULL;

    }

    if (myInfoPtr->wStreamRef)

    {

        CFWriteStreamClose(myInfoPtr->wStreamRef);

        myInfoPtr->wStreamRef = NULL;

    }

}


extern void StopWWAN(MyInfoRef infoRef)

{

    MyStreamInfoPtr myInfoPtr = (MyStreamInfoPtr)infoRef;

    

    printf("stopWWAN entered\n");

    assert(myInfoPtr != NULL);

    myInfoPtr->isConnected = FALSE;

    CleanupAfterWAAN(myInfoPtr);

    CloseStreams(myInfoPtr);

    free(myInfoPtr);

}



  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值