美文网首页iOS Developertom
使用GCDAsyncUdpSocket进行局域网广播寻址

使用GCDAsyncUdpSocket进行局域网广播寻址

作者: 丨n水瓶座菜虫灬 | 来源:发表于2016-11-17 17:38 被阅读374次
局域网内app搜索智能设备
步骤: 
1. app连接上智能设备所连接的wifi热点
2. app使用UdpSocket发送广播寻找设备
3. 设备收到广播后回复自己的ip地址和mac地址
4. 找到了对应的设备就可以进行数据通信
app使用UdpSocket发送广播寻址的逻辑如下:
1. 获取当前手机连接的wifi IP地址
2. 把IP地址最后的数字换成255,作为目标IP, 例如 手机当前IP地址为192.168.1.1 转换为目标IP后为 192.168.1.255,这样app发送广播时192.168.1.xx的设备都能收到广播信息。
3. 把目标IP作为Host,发送寻址指令到指定端口
4. 开启接收监听beginReceiving
获取当前手机wifi IP地址的方法如下:
// 需要导入头文件 <ifaddrs.h>和<arpa/inet.h>
- (NSString *)getIPAddress {
    NSString *address = @"error";
    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = 0;
    success = getifaddrs(&interfaces);
    if (success == 0) {
        temp_addr = interfaces;
        while (temp_addr != NULL) {
            if (temp_addr->ifa_addr->sa_family == AF_INET) {
                if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) {
                    address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in*)temp_addr->ifa_addr)->sin_addr)];
                }
            }
            temp_addr = temp_addr->ifa_next;
        }      
    }
    freeifaddrs(interfaces);
    NSLog(@"ip:%@", address);
    return address;
}

关于ifaddrs结构体自己画的图解如下:


ifaddrs结构体
创建GCDAsyncUdpSocket并设置代理,启动本地端口
self.udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];

// 启动本地端口
[self.udpSocket localPort];
广播寻址的方法如下
- (void)broadcastSearchCommandWithBlock:(BroadcastSearchCommandBlock)block {
    if (block) {// 此处的block是项目中用于回调数据
        self.broadcastBlock = block;
    }
    NSTimeInterval timeout = 1000;//发送超时时间
    NSString *request = @"Cmd%Search%End";// 查询指令,此指令与硬件、服务器沟通好
    NSData *data = [NSData dataWithData:[request dataUsingEncoding:NSASCIIStringEncoding]];
    NSLog(@"data:%@", data);
    UInt16 port = kPORT;// 端口
    NSError *error;

    // 发送广播设置
    [self.udpSocket enableBroadcast:YES error:&error];

    // 获取本地IP地址并用.分隔开放在数组中
    NSArray *strArr = [[self getIPAddress] componentsSeparatedByString:@"."];
    NSMutableArray *muArr = [NSMutableArray arrayWithArray:strArr];
    // 将数组的最后一位换成255
    [muArr replaceObjectAtIndex:(strArr.count-1) withObject:@"255"];
    // 将数组用.连接成目标IP地址字符串
    NSString *finalStr = [muArr componentsJoinedByString:@"."];// 目标ip

    NSLog(@"目标ip:%@", finalStr);
    // 发送广播寻址指令
    [self.udpSocket sendData:data toHost:finalStr port:port withTimeout:timeout tag:1];

    [self.udpSocket beginReceiving:nil];
}
实现GCDAsyncUdpSocketDelegate代理方法监听回调信息
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data fromAddress:(NSData *)address withFilterContext:(id)filterContext {
    NSString *result;
    result = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
    NSLog(@"resutl:%@",result); // 接收到的数据
    NSString *addr = [GCDAsyncUdpSocket hostFromAddress:address];// 从哪个IP地址发送来的数据
    NSLog(@"address:%@", addr);
}

- (void)udpSocket:(GCDAsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError *)error {
    NSLog(@"没有发送");
}

- (void)udpSocket:(GCDAsyncUdpSocket *)sock didSendDataWithTag:(long)tag {
    NSLog(@"已经发送");
}

- (void)udpSocketDidClose:(GCDAsyncUdpSocket *)sock withError:(NSError *)error {
    NSLog(@"关闭");
}

相关文章

网友评论

    本文标题:使用GCDAsyncUdpSocket进行局域网广播寻址

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