草庐IT

iOS 14.5+ 以后, CocoaAsyncSocket udp广播,组播,扫描失败----完美解决

微风_10a5 2023-10-08 原文

项目使用到了CocoaAsyncSocket,建立TCP之前,使用了UDP广播获取IP地址,给设备配置网络,但是系统升级到iOS 14.5之后,发现有台iPad间歇性可以收到广播,iPhone一直没有收到广播。甚至,发送组播时,会报错: Error Domain=NSPOSIXErrorDomain Code=65 "No route to host" UserInfo={NSLocalizedDescription=No route to host, NSLocalizedFailureReason=Error in send() function.}

原因:1.本地网络权限,2.组播权限

解决办法
1.在Info.plist,增加本地权限Privacy - Local Network Usage Description

localNetwork.png

2.发送一次UDP组播,触发权限弹框,让用户点击好,允许访问本地网络。

- (void)setupUdpSocket {
   NSError *error = nil;
   GCDAsyncUdpSocket *socket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
   self.udpSocket = socket;
   [socket setIPv4Enabled:YES];
   [socket setIPv6Enabled:NO];
   [socket bindToPort:udpPort error:&error];

   // 关键一行代码,发送广播,即使应用不需要。如果不发送,无法触发是否允许访问本地网络弹框。
   [self.udpSocket sendData:[@{} mj_JSONData] toHost:@"255.255.255.255" port:udpPort withTimeout:10 tag:100];

   [socket enableBroadcast:YES error:&error];
   [socket beginReceiving:&error];
}

3.申请组播权限的地址(关键的步骤)
申请网址https://developer.apple.com/contact/request/networking-multicast

requestEntry.png

3.1,你申请完了,苹果可能会在3天后给你回复邮件


image.png

3.2,这个时候,你需要再回复苹果的工作人员,使用组播的细节相关信息,下面是我的回复,仅供参考,如下:


image.png

3.3,大概3天后,你又会收到苹果的回复邮件,如下


image.png

3.4,那么恭喜你,权限申请成功,这个时候,你去登录develop网站,你就会发现,你多一项权限,如下:


image.png

3.5,勾选这个权限,代表你想要使用这个权限,如下


image.png

3.6,然后你要重新去生成一个provisioning profile(这个小伙伴们自己去操作喽)

4.现在需要在xcode上操作了
4.1,在xcode上,重新加一个provisioning profile,将刚刚生成的描述文件用起来(点击左下角,重新获取一次描述文件)


image.png

4.2,在xcode entitlement文件中,添加权限,如下图

image.png
    <key>com.apple.developer.networking.multicast</key>
    <true/>

4.3,可以验证一下配置provisioning file有没有生效,在终端可以输入以下代码,如果出现下图红框的代码,就证明成功了

security cms -D -i your provisioning profile path | grep -A 1 "com.apple.developer.networking.multicast"
image.png

5.赶紧来试一下最终效果吧,发送udp组播扫描


image.png
主要参考链接如下

[苹果开发者网站的问答]https://developer.apple.com/forums/thread/663271
[其他相关作者的文章]https://www.cnblogs.com/chao8888/p/13749383.html

结尾

这个问题从出现到解决,还是花费了不少时间,各种找原因,各种找资料,但资料少得可怜,大多都是类同的,没什么参考价值。故分享出来,希望给遇到同样问题的小伙伴们一些思路。看到这里的小伙们,或者觉得文章对你有点帮助的话,请点赞加关注喽,您的反馈就是我们前进的动力。后续会分享更多关于移动端的干货。谢谢~~

补充一下: 关于本地网络权限弹框
- (void)viewDidLoad {
    [super viewDidLoad];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        // 主动发送udp请求
        [[ScanX3UdpSocket shareScanX3UdpSocket] startScanX3];

    });
}

进入这个界面, 2秒后,第一次发送udp扫描,也就是第一次使用到本地网络,然后就会弹框出来,如下图


1.png

有关iOS 14.5+ 以后, CocoaAsyncSocket udp广播,组播,扫描失败----完美解决的更多相关文章

  1. ruby - 即使失败也继续进行多主机测试 - 2

    我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r

  2. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  3. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  4. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  5. ruby-on-rails - 创建 ruby​​ 数据库时惰性符号绑定(bind)失败 - 2

    我正在尝试在Rails上安装ruby​​,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf

  6. ruby - 正则表达式在哪个位置失败? - 2

    我需要一个非常简单的字符串验证器来显示第一个符号与所需格式不对应的位置。我想使用正则表达式,但在这种情况下,我必须找到与表达式相对应的字符串停止的位置,但我找不到可以做到这一点的方法。(这一定是一种相当简单的方法……也许没有?)例如,如果我有正则表达式:/^Q+E+R+$/带字符串:"QQQQEEE2ER"期望的结果应该是7 最佳答案 一个想法:你可以做的是标记你的模式并用可选的嵌套捕获组编写它:^(Q+(E+(R+($)?)?)?)?然后你只需要计算你获得的捕获组的数量就可以知道正则表达式引擎在模式中停止的位置,你可以确定匹配结束

  7. ruby - 使用 rbenv 和 ruby​​-build 构建 ruby​​ 失败,出现 undefined symbol : SSLv2_method - 2

    我正在尝试在配备ARMv7处理器的SynologyDS215j上安装ruby​​2.2.4或2.3.0。我用了optware-ng安装gcc、make、openssl、openssl-dev和zlib。我根据README中的说明安装了rbenv(版本1.0.0-19-g29b4da7)和ruby​​-build插件。.这些是随optware-ng安装的软件包及其版本binutils-2.25.1-1gcc-5.3.0-6gconv-modules-2.21-3glibc-opt-2.21-4libc-dev-2.21-1libgmp-6.0.0a-1libmpc-1.0.2-1libm

  8. ruby-on-rails - Ruby 的 'open_uri' 是否在读取或失败后可靠地关闭套接字? - 2

    一段时间以来,我一直在使用open_uri下拉ftp路径作为数据源,但突然发现我几乎连续不断地收到“530抱歉,允许的最大客户端数(95)已经连接。”我不确定我的代码是否有问题,或者是否是其他人在访问服务器,不幸的是,我无法真正确定谁有问题。本质上,我正在读取FTPURI:defself.read_uri(uri)beginuri=open(uri).readuri=="Error"?nil:urirescueOpenURI::HTTPErrornilendend我猜我需要在这里添加一些额外的错误处理代码...我想确保我采取一切预防措施来关闭所有连接,这样我的连接就不是问题所在,但是我

  9. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  10. ruby-on-rails - Ruby 流量控制 : throw an exception, 返回 nil 还是让它失败? - 2

    我在思考流量控制的最佳实践。我应该走哪条路?1)不要检查任何东西并让程序失败(更清晰的代码,自然的错误消息):defself.fetch(feed_id)feed=Feed.find(feed_id)feed.fetchend2)通过返回nil静默失败(但是,“CleanCode”说,你永远不应该返回null):defself.fetch(feed_id)returnunlessfeed_idfeed=Feed.find(feed_id)returnunlessfeedfeed.fetchend3)抛出异常(因为不按id查找feed是异常的):defself.fetch(feed_id

随机推荐