SCNetworkReachabilityRef監測網路狀態

OneAlon發表於2018-01-31

SCNetworkReachabilityRef介面可以確定當前主機的網路狀態以及目標主機的可達性, 可達性是指data packet(資料包)可以從當前主機傳送出去, 而不是目標主機可以接收到data packet(資料包).

SCNetworkReachabilityRef介面有同步和非同步兩種模式. 在同步模式下, 可以通過SCNetworkReachabilityGetFlags方法獲取網路狀態; 在非同步模式下, 可以排程一個SCNetworkReachability物件到客戶端的執行迴圈上, 客戶端實現一個回撥函式接收網路狀態變化的通知, 這個回撥函式遵循Core Foundation命名規範, 只要函式名中包含 "Create" 或 "Copy"的函式返回的引用,都必須呼叫CFRelease來釋放。

SCNetworkReachabilityRef中幾個主要的方法和屬性:

SCNetworkReachabilityContext結構體

typedef struct {
	CFIndex		version;
	void *		__nullable info;
	const void	* __nonnull (* __nullable retain)(const void *info);
	void		(* __nullable release)(const void *info);
	CFStringRef	__nonnull (* __nullable copyDescription)(const void *info);
} SCNetworkReachabilityContext;
複製程式碼

結構體中包含使用者指定的資料資訊和用於SCNetworkReachabilitySetCallback方法的回撥info. version為版本號, 作為引數傳遞給SCDynamicStore建立結構體型別的版本號. 這個結構體的版本號為0. info是一個C語言的指標物件, 這裡一般傳入當網路狀態發生改變時執行的block回撥, 個人理解為C語言的指標不在ARC的管理範圍內, 需要手動管理記憶體, 所以這裡傳入release inforetain info用於管理記憶體. 這個結構體需要在SCNetworkReachabilitySetCallback設定才能起作用.

建立網路連線引用

SCNetworkReachabilityRef SCNetworkReachabilityCreateWithAddress(CFAllocatorRef allocator, const struct sockaddr *address);
複製程式碼

通過傳入需要測試的IP地址建立網路連線引用, allocator可以設定為NULL或者kCFAllocatorDefault.

SCNetworkReachabilityRef SCNetworkReachabilityCreateWithName(CFAllocatorRef allocator, const char *nodename);
複製程式碼

通過傳入需要測試的網址建立網路連線引用, 同上個方法.

獲取網路連線狀態

Boolean SCNetworkReachabilityGetFlags(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags *flags);
複製程式碼

用於獲取網路連線的狀態, 傳入的第一個引數是SCNetworkReachabilityRef網路連線引用, 第二個引數用來儲存獲取的網路連線狀態, 如果能獲取到連線就返回true否則返回false.

網路狀態改變時的通知

Boolean SCNetworkReachabilitySetCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityCallBack callout, SCNetworkReachabilityContext *context);
複製程式碼

當網路狀態發生變化時, 就會呼叫callout, 第一個引數是網路連線引用, 第二個引數是回撥, 如果為NULL, 當前的target就會被移除, SCNetworkReachabilityCallBack的型別為(typedef void (*SCNetworkReachabilityCallBack)(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info);) callout回撥中的info引數就是從第三個引數context結構體中取的info回撥, 這樣就把結構體context中的資料傳到了SCNetworkReachabilityCallBack引數中, 第三個引數是與callout相關聯的上下文, 可能為空. 如果通知客戶端成功就返回true, 否則返回false.

Boolean SCNetworkReachabilityScheduleWithRunLoop(SCNetworkReachabilityRef target, CFRunLoopRef runLoop, CFStringRef runLoopMode);
複製程式碼

使用指定的執行迴圈和模式排程指定的網路目標, 第一個引數是網路連線引用, 第二個引數runloop迴圈, 第三個引數迴圈模式. 如果target執行成功就返回true, 否則返回false. 這裡將target加入指定的runloop中, 會一直監測target的網路狀態, 當網路狀態發生變化時就會執行SCNetworkReachabilitySetCallback方法中的callout回撥, 所以我們只需要定義一個SCNetworkReachabilityCallBack型別的block, 將其傳入SCNetworkReachabilitySetCallback方法中即可.

相關文章