局域網(wǎng)內(nèi)app搜索智能設(shè)備
步驟:
1. app連接上智能設(shè)備所連接的wifi熱點(diǎn)
2. app使用UdpSocket發(fā)送廣播尋找設(shè)備
3. 設(shè)備收到廣播后回復(fù)自己的ip地址和mac地址
4. 找到了對(duì)應(yīng)的設(shè)備就可以進(jìn)行數(shù)據(jù)通信
app使用UdpSocket發(fā)送廣播尋址的邏輯如下:
1. 獲取當(dāng)前手機(jī)連接的wifi IP地址
2. 把IP地址最后的數(shù)字換成255,作為目標(biāo)IP, 例如 手機(jī)當(dāng)前IP地址為192.168.1.1 轉(zhuǎn)換為目標(biāo)IP后為 192.168.1.255巢株,這樣app發(fā)送廣播時(shí)192.168.1.xx的設(shè)備都能收到廣播信息。
3. 把目標(biāo)IP作為Host,發(fā)送尋址指令到指定端口
4. 開啟接收監(jiān)聽beginReceiving
獲取當(dāng)前手機(jī)wifi IP地址的方法如下:
// 需要導(dǎo)入頭文件 <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;
}
關(guān)于ifaddrs結(jié)構(gòu)體自己畫的圖解如下:
創(chuàng)建GCDAsyncUdpSocket并設(shè)置代理腾夯,啟動(dòng)本地端口
self.udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
// 啟動(dòng)本地端口
[self.udpSocket localPort];
廣播尋址的方法如下
- (void)broadcastSearchCommandWithBlock:(BroadcastSearchCommandBlock)block {
if (block) {// 此處的block是項(xiàng)目中用于回調(diào)數(shù)據(jù)
self.broadcastBlock = block;
}
NSTimeInterval timeout = 1000;//發(fā)送超時(shí)時(shí)間
NSString *request = @"Cmd%Search%End";// 查詢指令,此指令與硬件蔬充、服務(wù)器溝通好
NSData *data = [NSData dataWithData:[request dataUsingEncoding:NSASCIIStringEncoding]];
NSLog(@"data:%@", data);
UInt16 port = kPORT;// 端口
NSError *error;
// 發(fā)送廣播設(shè)置
[self.udpSocket enableBroadcast:YES error:&error];
// 獲取本地IP地址并用.分隔開放在數(shù)組中
NSArray *strArr = [[self getIPAddress] componentsSeparatedByString:@"."];
NSMutableArray *muArr = [NSMutableArray arrayWithArray:strArr];
// 將數(shù)組的最后一位換成255
[muArr replaceObjectAtIndex:(strArr.count-1) withObject:@"255"];
// 將數(shù)組用.連接成目標(biāo)IP地址字符串
NSString *finalStr = [muArr componentsJoinedByString:@"."];// 目標(biāo)ip
NSLog(@"目標(biāo)ip:%@", finalStr);
// 發(fā)送廣播尋址指令
[self.udpSocket sendData:data toHost:finalStr port:port withTimeout:timeout tag:1];
[self.udpSocket beginReceiving:nil];
}
實(shí)現(xiàn)GCDAsyncUdpSocketDelegate
代理方法監(jiān)聽回調(diào)信息
- (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); // 接收到的數(shù)據(jù)
NSString *addr = [GCDAsyncUdpSocket hostFromAddress:address];// 從哪個(gè)IP地址發(fā)送來的數(shù)據(jù)
NSLog(@"address:%@", addr);
}
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError *)error {
NSLog(@"沒有發(fā)送");
}
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didSendDataWithTag:(long)tag {
NSLog(@"已經(jīng)發(fā)送");
}
- (void)udpSocketDidClose:(GCDAsyncUdpSocket *)sock withError:(NSError *)error {
NSLog(@"關(guān)閉");
}