ios appローカルエリアネットワーク内でデバイスを検索する方法


現在、多くのスマートホームのappは関連機器を自動的にスキャンする機能を持っており、ネットで検索してみるとudpの放送技術で実現されていることが分かった.
それからネット上でいくつかの資料を探した後、自分も2つのappを使って通信過程をシミュレートしました:そのうちの1つの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
"); return false; } /* Create the UDP socket */ if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { printf("Failed to create socket
"); 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
"); 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
", 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
", strerror(errno)); NSLog([NSString stringWithUTF8String:buffer]); // [self parseRX:[NSString stringWithFormat:@"
以上のコードは同じ携帯電話でテストされ、通信は正常です.