如何在ios app 局域网内搜索到设备

来源:互联网 发布:网络连接受限制怎么办 编辑:程序博客网 时间:2024/05/18 01:03
现在很多智能家居的app都具有自动扫瞄关联设备的功能,在网上搜索了一下,了解到是通过udp的广播技术来实现的。

然后在网上查找了一些资料后,自己也使用两个app模拟了一下通信过程:其中一个app模拟设备端。

app端主要代码:用户发送了一个广播以后再启动一个监听socket,负责搜集设备返回来的设备信息。

//UDP Broadcast Sockets-(bool) send:(NSString*) msg ipAddress:(NSString*) ip port:(int) p{    int sock;    struct sockaddr_in destination;    unsigned int echolen;    int broadcast = 1;    // if that doesn't work, try this    //char broadcast = '1';        if (msg == nil || ip == nil)    {        printf("Message and/or ip address is null\n");        return false;    }        /* Create the UDP socket */    if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)    {        printf("Failed to create socket\n");      return false;    }        /* Construct the server sockaddr_in structure */    memset(&destination, 0, sizeof(destination));        /* Clear struct */    destination.sin_family = AF_INET;        /* Internet/IP */    destination.sin_addr.s_addr = inet_addr([ip UTF8String]);        /* IP address */    destination.sin_port = htons(p);        /* server port */    setsockopt(sock,               IPPROTO_IP,               IP_MULTICAST_IF,               &destination,               sizeof(destination));    char *cmsg = [msg UTF8String];   echolen = strlen(cmsg);        // this call is what allows broadcast packets to be sent:    if (setsockopt(sock,                   SOL_SOCKET,                   SO_BROADCAST,                   &broadcast,                   sizeof broadcast) == -1)    {        perror("setsockopt (SO_BROADCAST)");        exit(1);    }    if (sendto(sock,               cmsg,               echolen,               0,               (struct sockaddr *) &destination,               sizeof(destination)) != echolen)    {        printf("Mismatch in number of sent bytes\n");        return false;    }    else    {        [NSThread detachNewThreadSelector:@selector(startServer)                                 toTarget:self                               withObject:nil];        NSLog([NSString stringWithFormat:@"-> Tx: %@",msg]);        return true;    }    }- (void)startServer {    NSLog(@"UDP listen started...");    int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);    struct sockaddr_in sa;    char buffer[1024];    size_t fromlen, recsize;        memset(&sa, 0, sizeof(sa));    sa.sin_family = AF_INET;    sa.sin_addr.s_addr = INADDR_ANY;    sa.sin_port = htons(3000);        // bind the socket to our address    if (-1 == bind(sock,(struct sockaddr *)&sa, sizeof(struct sockaddr)))    {        perror("error bind failed");        close(sock);        exit(EXIT_FAILURE);    }        for (;;)    {        recsize = recvfrom(sock,                           (void *)buffer,                           1024,                           0,                           (struct sockaddr *)&sa,                           &fromlen);                if (recsize < 0)            fprintf(stderr, "%s\n", strerror(errno));                NSLog([NSString stringWithUTF8String:buffer]);            }}- (IBAction)send:(id)sender {    [self send:self.message.text ipAddress:@"255.255.255.255" port:5009];    }


模拟设备端主要代码:程序一启动就有一个监听线程,当监听到广播信息后,从该端口报告数据上去。

//UDP Server- (void)startServer {    NSLog(@"UDP Server started...");    int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);    struct sockaddr_in sa;    char buffer[1024];    size_t fromlen, recsize;        memset(&sa, 0, sizeof(sa));    sa.sin_family = AF_INET;    sa.sin_addr.s_addr = INADDR_ANY;    sa.sin_port = htons(5009);        // bind the socket to our address    if (-1 == bind(sock,(struct sockaddr *)&sa, sizeof(struct sockaddr)))    {        perror("error bind failed");        close(sock);        exit(EXIT_FAILURE);    }        for (;;)    {        recsize = recvfrom(sock,                           (void *)buffer,                           1024,                           0,                           (struct sockaddr *)&sa,                           &fromlen);                if (recsize < 0)            fprintf(stderr, "%s\n", strerror(errno));                NSLog([NSString stringWithUTF8String:buffer]);               // [self parseRX:[NSString stringWithFormat:@"<- Rx: %s",buffer]];                char str[INET_ADDRSTRLEN];        struct sockaddr_in  cms;        int n;        inet_ntop(AF_INET, &sa.sin_addr, str, INET_ADDRSTRLEN);        cms.sin_family = AF_INET;inet_pton(AF_INET, str, &cms.sin_addr);cms.sin_port = htons(3000);                char pResponse[] = "i am device no 1";        n = sendto(sock, pResponse, strlen(pResponse), 0,                   (struct sockaddr *) &cms, sizeof(cms));if (n < 0) {perror("sendto");}    }    //[pool release];}- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{    // Override point for customization after application launch.            [NSThread detachNewThreadSelector:@selector(startServer)                             toTarget:self                           withObject:nil];    return YES;}
以上代码在同一个手机上测试过,通信正常。

0 0
原创粉丝点击