美文网首页
iOS 给iot设备配网

iOS 给iot设备配网

作者: 呦释原点 | 来源:发表于2018-11-15 10:13 被阅读77次
    1.需求描述

    手机端发送组播给iot设备, iot设备根据接收到的组播信息,链接wifi,链接成功后发送广播告诉手机已连接成功
    此处只展示实现组播的功能, 发送什么数据, 怎么发送, 发送多少暂时不讨论

    2. 准备工作

    手机端组播,需要使用UDP, 已有现成的GCDAsyncUdpSocket可用,可以节省一部分工作

    3. 砌砖

    关于GCDAsyncUdpSocket的使用网上有很多文档,只展示出实现组播功能的一小部分, 当然为了封装成SDK将GCDAsyncUdpSocket 转换成了LZXAsyncUdpSocket 以免项目中再次用到 GCDAsyncUdpSocket 时 冲突

    1. 初始化
    - (LZXAsyncUdpSocket *)udpSocket {
        if (_udpSocket == nil) {
            dispatch_queue_t DeletageQueue = dispatch_queue_create("DelegateQueue", DISPATCH_QUEUE_SERIAL);
            dispatch_queue_t SocketQueue = dispatch_queue_create("SocketQueue", DISPATCH_QUEUE_SERIAL);
            // 因为iot对接收的包的顺序有要求,此处使用串行队列执行任务
            _udpSocket = [[LZXAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:DeletageQueue socketQueue:SocketQueue];
    
            NSError *error = nil;
            [_udpSocket bindToPort:8888 error:&error];
            if (error) {
                NSLog(@"绑定端口失败");
            }
            [_udpSocket enableBroadcast:YES error:&error];
            if (error) {
                NSLog(@"启用广播失败");
            }
            [_udpSocket beginReceiving:&error];
            if (error) {
                NSLog(@"启用接受失败");
            }
        }
        return _udpSocket;
    }
    
    1. 发送数据
      NSString *host = [NSString stringWithFormat:@"%lu", ipAddr];
        uint16_t port = 8888;//通过端口监测
      // 如果拿到的是16进制地址, 需要转换一下
        host = [self longToIp:(NSInteger)ipAddr];
        [self.udpSocket sendData:data toHost:host port:port withTimeout:10 tag:0];
    
    1. 实现代理方法
    
    - (void)udpSocket:(LZXAsyncUdpSocket *)sock didConnectToAddress:(NSData *)address {
    //    NSLog(@"已经连接");
    }
    - (void)udpSocket:(LZXAsyncUdpSocket *)sock didNotConnect:(NSError *)error {
    //    NSLog(@"连接失败");
    }
    - (void)udpSocket:(LZXAsyncUdpSocket *)sock didSendDataWithTag:(long)tag {
    //    NSLog(@"发送成功  %ld", tag );
    }
    - (void)udpSocket:(LZXAsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError *)error {
    //    NSLog(@"发送失败 %@", error);
    }
    
    - (void)udpSocket:(LZXAsyncUdpSocket *)sock didReceiveData:(NSData *)data fromAddress:(NSData *)address withFilterContext:(id)filterContext {
        NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        if ([s isEqualToString:@"success"]) {
            // 联网成功停止发送,并提示成功
        }
    }
    
    - (void)udpSocketDidClose:(LZXAsyncUdpSocket *)sock withError:(NSError *)error {
    }
    
    5. 注意点
    1. 接收广播时监听的端口和广播端发送的端口要一致。
    2. 如果要进行广播/组播数据,必须只能使用[socket bindToPort:54321 error:&error] 方法来绑定端口,不能绑定IP地址并且启用广播,否则不能广播数据。
    3. 该实例没有被销毁前,只能被创建一次,因为端口正在被使用
    6. 其他
    1. iot设备接收的组播报有同步报、数据报、接收完成报三部分组成,所以配网一次需要发送很多数据报
    2. 报文之前需要有几毫秒的时间间隔让设备接收反应
    3. 此次iot设备是根据数据报的长度获取的数据, 跟发送的内容没有关系,所以在使用GCDAsyncUdpSocket时,在其内部单独添加了数据长度的属性已便自己设备数据长度,而不是获取的buffer的长度
    4. iot设备按顺序接收数据报, 从有序的数据报中解析数据, 所有发送数据报也需要有序发送
    7. 参考

    单播、组播、广播差别: https://www.cnblogs.com/wzjhoutai/p/6917477.html
    GCDAsyncUdpSocket 组播监听端口接收数据 https://blog.csdn.net/nogodoss/article/details/27313043

    相关文章

      网友评论

          本文标题:iOS 给iot设备配网

          本文链接:https://www.haomeiwen.com/subject/rsyefqtx.html