iOS開發(fā),開啟熱點(diǎn)幕随,255.255.255.255發(fā)送UDP廣播問題

一蚁滋,前言

小編在目前在做智能硬件方面的項(xiàng)目,遇到一個(gè)需求赘淮,就是開啟手機(jī)熱點(diǎn)辕录,然后將智能設(shè)備配網(wǎng)連接到手機(jī)上,手機(jī)發(fā)送UDP廣播查找設(shè)備梢卸。

二走诞,問題

手機(jī)通過 255.255.255.255 地址進(jìn)行UDP廣播,設(shè)備沒有收到消息蛤高,連接同一個(gè)熱點(diǎn)的設(shè)備通過是能收到廣播消息的蚣旱,并且能相互通信。

三襟齿,個(gè)人分析

手機(jī)是連接著4G網(wǎng)絡(luò)姻锁,并且開啟熱點(diǎn),如果直接通過 255.255.255.255 地址進(jìn)行廣播的話猜欺,它怎么知道該廣播到外網(wǎng)去呢還是手機(jī)熱點(diǎn)的網(wǎng)段位隶,因此猜測(cè)應(yīng)該對(duì)指定的網(wǎng)段進(jìn)行廣播.

四,通過局域網(wǎng) IP 計(jì)算網(wǎng)絡(luò)廣播地址

網(wǎng)段IP = 子網(wǎng)掩碼&IP
網(wǎng)段最大地址 = ~(子網(wǎng)掩碼)
廣播地址 = 網(wǎng)段地址 + 網(wǎng)段最大地址;

例如:

IP:172.20.10.10/28
子網(wǎng)掩碼:255.255.255.240
子網(wǎng)掩碼二進(jìn)制:11111111 11111111 11111111 11110000

網(wǎng)段IP = 172.20.10.10 & 255.255.255.240 (按位與) = 172.20.10.0
網(wǎng)段最大地址 = ~(255.255.255.240 ) = 15
廣播地址 = 172.20.10.0 + 15 = 172.20.10.15

也可以使用在線工具計(jì)算 http://ip.chacuo.net/ipcalc
其他的網(wǎng)絡(luò)知識(shí)請(qǐng)百度 "子網(wǎng)掩碼","IP","廣播地址","局域網(wǎng)廣域網(wǎng)","IP地址分類" ,"IP地址分類主機(jī)數(shù)量"等關(guān)鍵字

五开皿,實(shí)踐看看是否是這樣

1.首先我們?cè)?G網(wǎng)絡(luò)環(huán)境下開啟熱點(diǎn)


Screen Shot 2018-10-24 at 下午5.12.33.png

2.使用另一臺(tái)設(shè)備連接該熱點(diǎn)涧黄,并查看該熱點(diǎn)的詳細(xì)信息


Screenshot_2018-10-24-17-18-57-026_com.android.se.png

可以拿到設(shè)備的ip(172.20.10.10) 子網(wǎng)掩碼(255.255.255.240)
通過第四點(diǎn)可以計(jì)算出子 廣播地址為172.20.10.15

然后在手機(jī)上或電腦上安裝一些網(wǎng)絡(luò)調(diào)試助手調(diào)試UDP
軟件推薦:
MAC:PacketSender
iOS:TCP/UDP
Android:網(wǎng)絡(luò)測(cè)試
Windows:網(wǎng)絡(luò)調(diào)試助手

小編拿iPhone 和 Android 機(jī)進(jìn)行測(cè)試,iPhone開啟熱點(diǎn)赋荆,Android模擬設(shè)備笋妥。

iPhone


Screen Shot 2018-10-24 at 下午5.36.01.png

Android

Screenshot_2018-10-24-17-36-01-841_mellow.cyan.ne.png

可以發(fā)現(xiàn)開啟熱點(diǎn)的手機(jī)是可以見數(shù)據(jù)廣播到局域網(wǎng)中的。

六窄潭,iOS 相關(guān)代碼

獲取熱點(diǎn)手機(jī)在局域網(wǎng)中的IP地址
UIDevice+GBCategory.h

#import <UIKit/UIKit.h>
#include <ifaddrs.h>
#include <arpa/inet.h>
#include <net/if.h>

#define IOS_CELLULAR    @"pdp_ip0"
#define IOS_WIFI        @"en0"
//#define IOS_VPN       @"utun0"
#define IP_ADDR_IPv4    @"ipv4"
#define IP_ADDR_IPv6    @"ipv6"

@interface UIDevice(GBCategory)
- (NSDictionary *)getIPAddresses;



- (NSString *)getIPAddress:(BOOL)preferIPv4;




/**
 獲取熱點(diǎn)地址
 
 @param preferIPv4 <#preferIPv4 description#>
 @return <#return value description#>
 */
- (NSString *)getHotSpotIp;

/**
 獲取熱點(diǎn)子網(wǎng)掩碼
 
 @param preferIPv4 <#preferIPv4 description#>
 @return <#return value description#>
 */
- (NSString *)getHotSpotMask;



/**
 獲取熱點(diǎn)網(wǎng)絡(luò)廣播地址

 @return <#return value description#>
 */
- (NSString *)getHotSpotBroadcastIp;


- (BOOL)flagWithOpenHotSpot;

@end


UIDevice+GBCategory.m

#import "UIDevice+GBCategory.h"
#import <UIDevice+YYAdd.h>
@implementation UIDevice(GBCategory)
- (NSDictionary *)getIPAddresses
{
    NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8];
    
    // retrieve the current interfaces - returns 0 on success
    struct ifaddrs *interfaces;
    if(!getifaddrs(&interfaces)) {
        // Loop through linked list of interfaces
        struct ifaddrs *interface;
        for(interface=interfaces; interface; interface=interface->ifa_next) {
            if(!(interface->ifa_flags & IFF_UP) /* || (interface->ifa_flags & IFF_LOOPBACK) */ ) {
                continue; // deeply nested code harder to read
            }
            const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr;
            const struct sockaddr_in *netmask = (const struct sockaddr_in*)interface->ifa_netmask;
            
            
            
            
            
            char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ];
            if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) {
                NSString *name = [NSString stringWithUTF8String:interface->ifa_name];
                NSString *type;
                if(addr->sin_family == AF_INET) {
                    if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) {
                        type = IP_ADDR_IPv4;
                    }
                } else {
                    const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)interface->ifa_addr;
                    if(inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, INET6_ADDRSTRLEN)) {
                        type = IP_ADDR_IPv6;
                    }
                }
                if(type) {
                    NSString *key = [NSString stringWithFormat:@"%@/%@", name, type];
                    addresses[key] = [NSString stringWithUTF8String:addrBuf];
                }
                
                if (netmask) {
                    
                    NSString *sin_addr = [NSString stringWithUTF8String:inet_ntoa(addr->sin_addr)];
                    NSString *ifa_netmask = [NSString stringWithUTF8String:inet_ntoa(netmask->sin_addr)];
                    
                    NSString *key = [NSString stringWithFormat:@"ifa_netmask/%@", type];
                    addresses[key] = ifa_netmask;
                    NSLog(@"ip Info sin_addr:%@ - %@",sin_addr,ifa_netmask);
                }
            }
        }
        // Free memory
        freeifaddrs(interfaces);
    }
    return [addresses count] ? addresses : nil;
}

- (NSString *)getIPAddress:(BOOL)preferIPv4
{
    NSArray *searchArray = preferIPv4 ?
    @[ /*IOS_VPN @"/" IP_ADDR_IPv4, IOS_VPN @"/" IP_ADDR_IPv6,*/ IOS_WIFI @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6 ] :
    @[ /*IOS_VPN @"/" IP_ADDR_IPv6, IOS_VPN @"/" IP_ADDR_IPv4,*/ IOS_WIFI @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4 ] ;
    
    NSDictionary *addresses = [self getIPAddresses];
    NSLog(@"addresses: %@", addresses);
    
    __block NSString *address;
    [searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop)
     {
         address = addresses[key];
         if(address) *stop = YES;
     } ];
    return address ? address : @"0.0.0.0";
}


- (NSString *)getHotSpotIp{
    NSDictionary *dict = [self getIPAddresses];
    if ( dict ) {
        NSArray *keys = dict.allKeys;
        for ( NSString *key in keys) {
            if ( key && [key containsString:@"bridge"] && [key containsString:@"ipv4"])
                return dict[key];
        }
    }
    return @"0.0.0.0";
}

- (NSString *)getHotSpotMask{
    NSDictionary *dict = [self getIPAddresses];
    if ( dict ) {
        NSArray *keys = dict.allKeys;
        for ( NSString *key in keys) {
            if ( key && [key containsString:@"ifa_netmask"] && [key containsString:@"ipv4"])
                return dict[key];
        }
    }
    return @"0.0.0.0";
}

- (NSString *)getHotSpotBroadcastIp{
    NSString *ip = [self getHotSpotIp];
    NSString *mask = [self getHotSpotMask];
    NSArray *ips = [ip componentsSeparatedByString:@"."];
    NSArray *masks = [mask componentsSeparatedByString:@"."];
    
    NSMutableString *b_address = [[NSMutableString alloc] init]; //網(wǎng)段地址
    for (int index = 0; index < 4; index ++) {
        unsigned char value =  [ips[index] unsignedCharValue] & [masks[index] unsignedCharValue];
        if (index!=3) {
            
            [b_address appendFormat:@"%d.",value];
        }else{
            unsigned char v = (~[masks[index] unsignedCharValue]) + value;
            [b_address appendFormat:@"%d",v];
        }
        
    }
    return b_address;
}



- (BOOL)flagWithOpenHotSpot
{
    NSDictionary *dict = [self getIPAddresses];
    if ( dict ) {
        NSArray *keys = dict.allKeys;
        for ( NSString *key in keys) {
            if ( key && [key containsString:@"bridge"])
                return YES;
        }
    }
    return NO;
}

@end
 

獲取熱點(diǎn)名稱

NSString *hotpotName = [[UIDevice currentDevice] name];

以上僅為個(gè)人理解春宣,如有錯(cuò)誤請(qǐng)指正,謝謝!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末月帝,一起剝皮案震驚了整個(gè)濱河市躏惋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嚷辅,老刑警劉巖簿姨,帶你破解...
    沈念sama閱讀 221,430評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異簸搞,居然都是意外死亡扁位,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門趁俊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)域仇,“玉大人,你說(shuō)我怎么就攤上這事则酝⊙臭ぃ” “怎么了闰集?”我有些...
    開封第一講書人閱讀 167,834評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵沽讹,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我武鲁,道長(zhǎng)爽雄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,543評(píng)論 1 296
  • 正文 為了忘掉前任沐鼠,我火速辦了婚禮挚瘟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘饲梭。我一直安慰自己乘盖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,547評(píng)論 6 397
  • 文/花漫 我一把揭開白布憔涉。 她就那樣靜靜地躺著订框,像睡著了一般。 火紅的嫁衣襯著肌膚如雪兜叨。 梳的紋絲不亂的頭發(fā)上穿扳,一...
    開封第一講書人閱讀 52,196評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音国旷,去河邊找鬼矛物。 笑死,一個(gè)胖子當(dāng)著我的面吹牛跪但,可吹牛的內(nèi)容都是我干的履羞。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼忆首!你這毒婦竟也來(lái)了骨杂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,671評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤雄卷,失蹤者是張志新(化名)和其女友劉穎搓蚪,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丁鹉,經(jīng)...
    沈念sama閱讀 46,221評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡妒潭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,303評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了揣钦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雳灾。...
    茶點(diǎn)故事閱讀 40,444評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖冯凹,靈堂內(nèi)的尸體忽然破棺而出谎亩,到底是詐尸還是另有隱情,我是刑警寧澤宇姚,帶...
    沈念sama閱讀 36,134評(píng)論 5 350
  • 正文 年R本政府宣布匈庭,位于F島的核電站,受9級(jí)特大地震影響浑劳,放射性物質(zhì)發(fā)生泄漏阱持。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,810評(píng)論 3 333
  • 文/蒙蒙 一魔熏、第九天 我趴在偏房一處隱蔽的房頂上張望衷咽。 院中可真熱鬧,春花似錦蒜绽、人聲如沸镶骗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)鼎姊。三九已至,卻和暖如春吏夯,著一層夾襖步出監(jiān)牢的瞬間此蜈,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工噪生, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留裆赵,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,837評(píng)論 3 376
  • 正文 我出身青樓跺嗽,卻偏偏與公主長(zhǎng)得像战授,于是被迫代替她去往敵國(guó)和親页藻。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,455評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 1植兰、概念簡(jiǎn)介 子網(wǎng)掩碼子網(wǎng)掩碼又叫網(wǎng)絡(luò)掩碼份帐、地址掩碼,是一個(gè)32位地址楣导,用于屏蔽IP地址的一部分以區(qū)別網(wǎng)絡(luò)號(hào)和主機(jī)...
    黒貓閱讀 7,659評(píng)論 0 23
  • 名詞延伸 通俗的說(shuō),域名就相當(dāng)于一個(gè)家庭的門牌號(hào)碼毡咏,別人通過這個(gè)號(hào)碼可以很容易的找到你驮宴。如果把IP地址比作一間房子...
    楊大蝦閱讀 20,605評(píng)論 2 57
  • 計(jì)算機(jī)網(wǎng)絡(luò)學(xué)習(xí)的核心內(nèi)容就是網(wǎng)絡(luò)協(xié)議的學(xué)習(xí)。網(wǎng)絡(luò)協(xié)議是為計(jì)算機(jī)網(wǎng)絡(luò)中進(jìn)行數(shù)據(jù)交換而建立的規(guī)則呕缭、標(biāo)準(zhǔn)或者說(shuō)是約定的集...
    程序員必修課閱讀 2,019評(píng)論 2 64
  • IP地址的分類(記住) IP地址分為A類、B類离熏、C類佳谦、D類戴涝、E類滋戳,規(guī)定如下: A類:網(wǎng)絡(luò)位8位轴猎,主機(jī)位24位陕壹,網(wǎng)絡(luò)...
    Arya鑫閱讀 12,945評(píng)論 1 18
  • 引言 我先拋出一個(gè)簡(jiǎn)單的問題。 我所在的公司啟用的是獨(dú)立IP地址浸剩,公司下的所有電腦都在一個(gè)局域網(wǎng)內(nèi)可帽,然從每臺(tái)計(jì)算機(jī)...
    OzanShareing閱讀 5,310評(píng)論 2 23