iOS組播的那些坑

一、組播那些坑

1、發(fā)不出UDP數(shù)據(jù)包

1.1、 原因一:未開啟網(wǎng)絡(luò)權(quán)限

ios12后要開啟網(wǎng)絡(luò)權(quán)限才能把包發(fā)出去,不開啟網(wǎng)絡(luò)權(quán)限發(fā)不出udp包(不管是廣播還是組播),提示如下

no route to host

解決方案:開啟網(wǎng)絡(luò)權(quán)限“Access WiFi Information”

截屏2019-11-19下午3.03.18.png

1.2、 原因一:TTL設(shè)置轉(zhuǎn)發(fā)數(shù)不夠

GCDAsyncUdpSocket中默認TTL參數(shù)為1,TTL每轉(zhuǎn)發(fā)一級就減1,減到0就不轉(zhuǎn)發(fā),手機發(fā)送到路由器一級,就減少到0了,路由器就不會轉(zhuǎn)發(fā)出去了。

解決方案:修改TTL的值

   __block typeof(self) bself = self;
     [clientUdpSocket performBlock:^{
         char ttl = 16;//默認為1
         int ret = 0;
         int socketFd = [bself->clientUdpSocket socketFD];
         ret = setsockopt(socketFd, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl));
         if (ret != 0) {
             [self->clientUdpSocket close];
             self->clientUdpSocket = nil;
             });
         }
     }];

2、IP包加入組報錯

2.1、原因一:未綁定端口
join multicastGroup failure error:Error Domain=GCDAsyncUdpSocketErrorDomain Code=1 "Must bind a socket before joining a multicast group." UserInfo={NSLocalizedDescription=Must bind a socket before joining a multicast group.

解決方案:socket綁定端口號

[clientUdpSocket bindToPort:0 error:&error]
2.2、原因二:重復(fù)添加
Error Domain=NSPOSIXErrorDomain Code=48 "Address already in use" 
UserInfo={NSLocalizedDescription=Address already in use, 
NSLocalizedFailureReason=Error in setsockopt() function}

解決方案:不使用時需移除,這樣才能保證下次添加不報錯

[clientUdpSocket leaveMulticastGroup:host error:&error];
2.3、原因三:添加組播地址報如下錯【偶現(xiàn)】
join multicastGroup failure error:Error
Domain=NSPOSIXErrorDomain Code=12 "Cannot allocate
memory" UserInfo={NSLocalizedDescription=Cannot allocate
memory, NSLocalizedFailureReason=Error in setsockopt() function} 

解決方案\color{red}{偶現(xiàn)現(xiàn)象,暫時不知道原因,如有知道的請告知}

3、關(guān)于SSID和BSSID的獲取

3.1、iOS13 獲取不到SSID和BSSID

解決方案

  • 開啟定位
  • 開啟網(wǎng)絡(luò)權(quán)限“Access WiFi Information”
3.2、定位權(quán)限開啟不生效

info.list添加了以下權(quán)限,但是還是未彈出授權(quán)Alter

NSLocationAlwaysUsageDescription NSLocationWhenInUseUsageDescription

應(yīng)用設(shè)置中也沒有定位選項,如下

image.png

解決方案

你要獲取權(quán)限self.locationManager requestWhenInUseAuthorization

這個是在運行期間使用,另外一個是后臺使用,你要用哪個就選擇哪個

你先判斷你的定位是否可行,如果行就判斷是什么情況,如沒有權(quán)限就去申請,如果是用戶拒絕了,就是跳轉(zhuǎn)到設(shè)置

 

-(void)clickToMapVC{

    

    //確定用戶的位置服務(wù)是否啟用,位置服務(wù)在設(shè)置中是否被禁用

    BOOL enable      =[CLLocationManager locationServicesEnabled];

    NSInteger status =[CLLocationManager authorizationStatus];

    if(  !enable || status< 2){

        //尚未授權(quán)位置權(quán)限

        if ([[UIDevice currentDevice].systemVersion floatValue] >= 8)

        {

            //系統(tǒng)位置授權(quán)彈窗

            _lManager =[[CLLocationManager alloc]init];

            [_lManager requestAlwaysAuthorization];

            [_lManager requestWhenInUseAuthorization];

            

              [self initLocation];

        }

    }else{

        if (status == kCLAuthorizationStatusDenied) {

            //拒絕使用位置

           [Helper showSettingAlertStr:@"上傳圖片需要開啟位置授權(quán),請在iPhone的“設(shè)置->隱私->位置”中打開本應(yīng)用的訪問權(quán)限"];

        }else{

//            //允許使用位置

            

             [self initLocation];

 

        }

    

}

    

}

4、收包端收到其他包

4.1 收到其他數(shù)據(jù)包,判斷不準問題

解決方案:如下:

截屏2019-11-29下午5.54.22.png

二、補充知識點

1、端口為0

Port 0 is officially a reserved port in TCP/IP networking, meaning
that it should not be used for any TCP or UDP network
communications. However, port 0 sometimes takes on a special
meaning in network programming, particularly Unix socket
programming. In that environment, port 0 is a programming
technique for specifying system-allocated (dynamic) ports.

端口號 0 是一個預(yù)留的端口號,代表的意思就是它在TCP或者UDP網(wǎng)絡(luò)傳輸中應(yīng)該不會被用到。但是在網(wǎng)絡(luò)編程中,尤其是在unix socket編程當中,它有一些特殊的含義。在unix socket編程當中,端口號 0 是一種由系統(tǒng)指定動態(tài)生成的端口。

Description:

Configuring a new socket connection requires assigning a TCP or
UDP port number. Instead of hard-coding a particular port number,
or writing code that searches for an available port on the local
system, network programmers can instead specify port 0 as a
connection parameter. That triggers the operating system to
automatically search for and return the next available port in the
dynamic port number range.Unix, Windows and other operating
systems vary slightly in their handling of port 0.

當建立新的TCP和UDP socket連接時,需要給它們指定端口號。 為了避免這種寫死端口號的做法或者說為了從本地系統(tǒng)中找到可用端口。網(wǎng)絡(luò)編程員們可以以端口號0來作為連接參數(shù)。這樣的話操作系統(tǒng)就會從動態(tài)端口號范圍內(nèi)搜索接下來可以使用的端口號。windows系統(tǒng)和其他操作系統(tǒng)在處理端口號0時有一些細微的差別。

2、關(guān)于TTL

每當路由器轉(zhuǎn)發(fā)組播數(shù)據(jù)包,IP包中的TTL(Time To Live)值都減1。若數(shù)據(jù)包的TTL減少到0,則路由器將拋棄該數(shù)據(jù)包。TTL閾值可用于組播路由器的各個接口,以防止在該接口上轉(zhuǎn)發(fā)低于TTL閾值的組播數(shù)據(jù)包。這樣可對組播的范圍加以控制。下表給出典型的初始TTL值和作為不同TTL邊界的路由器接口TTL閾值。

范圍 初始值 TTL閾值
本地網(wǎng) 1 N/A
區(qū)域 15 16
地球 63 64
全球 127 128

3、關(guān)于IP

組播地址使用的是D類地址,D類IP地址(224.0.0.0到239.255.255.255)不識別互聯(lián)網(wǎng)內(nèi)的單個接口,但識別接口組,被稱為多播組。D類地址的的范圍及含義如下表:

| D類地址范圍 | 含義 |
| ------- | :-------- | :--- |
| 224.0.0.0 ~ 224.0.0.255 | 預(yù)留的組播地址(永久組地址),地址224.0.0.0保留不做分配,其他地址供路由協(xié)議使用,路由器不做轉(zhuǎn)發(fā)。 |
| 224.0.1.0 ~ 224.0.1.255 | 公用組播地址,用戶可用的組播地址(臨時組地址),全網(wǎng)范圍內(nèi)有效|
| 224.0.2.0 ~ 238.255.255.255 | 為用戶可用的組播地址(臨時組地址),全網(wǎng)范圍內(nèi)有效; |
| 239.0.0.0 ~ 239.255.255.255 | 本地管理組播地址,僅在特定的本地范圍有效 |

更多關(guān)于IP地址的資料:IP地址劃分、組播地址、公有IP、私有IP

4、 組播IP和組播MAC

首先IP地址是在網(wǎng)絡(luò)層的,MAC地址(也成為物理地址或硬件地址),物理地址是數(shù)據(jù)鏈路層和物理層使用的地址。物理地址已經(jīng)固化在網(wǎng)卡上,是不會變的,你電腦上的MAC地址是唯一的。
在類似以太網(wǎng)的網(wǎng)絡(luò)中,使用單播地址時,ARP通常根據(jù)目的地的IPv4地址確定其MAC地址,而在IPv6中則是由鄰居發(fā)現(xiàn)協(xié)議(ND)來承擔類似工作。在廣播中,一個MAC地址可以用于達到一個LANVLAN上的所有站點。那么組播中應(yīng)該如何確定何種MAC地址應(yīng)該放置于鏈路層幀中呢?理想的情況下,我們不必使用協(xié)議報文來確定適當?shù)腗AC地址,而是簡單地將一個IP組播地址直接映射到一些對應(yīng)的MAC地址。這些網(wǎng)絡(luò)代表了使用IP組播的最常見的網(wǎng)絡(luò)類型,具體映射方法在IPv4和IPv6中略有不同

4.1、IPv4組播MAC地址

IANA規(guī)定,IPv4組播MAC地址的高24位為0x01005E,第25位為0,低23位為IPv4組播地址的低23位。IPv4組播地址與MAC地址的映射關(guān)系如下圖所示。

image.png

由于IPv4組播地址的高4位是1110,代表組播標識,而低28位中只有23位被映射到IPv4組播MAC地址,這樣IPv4組播地址中就有5位信息丟失。于是,就有32個IPv4組播地址映射到了同一個IPv4組播MAC地址上,因此在二層處理過程中,設(shè)備可能要接收一些本IPv4組播組以外的組播數(shù)據(jù),而這些多余的組播數(shù)據(jù)就需要設(shè)備的上層進行過濾了。

VRRP4的組播IP:224.0.0.18 組播Mac:0100-5e00-0012

4.2、IPV6對應(yīng)的MAC地址

映射規(guī)則:組播MAC地址的前16位固定為0x3333,將組播IPV6地址的后32位直接映射到組播MAC地址的后32位就可以了。


image.png

如:IPV6地址為--FF12::1234:5678/64
對應(yīng)的組播MAC地址為--3333:1234:5678

VRRP6的組播IP:FF02::12組播Mac:3333-0000-0012

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容