// // UDPManager.m // 2cu // // Created by wutong on 15-1-13. // Copyright (c) 2015年 guojunyi. All rights reserved. // #import "UDPManager.h" #import #import #import #import "LocalDevice.h" #import "ContactDAO.h" #import "Contact.h" #import "mesg.h" #import "Utils.h" #import "AppDelegate.h" @implementation UDPManager + (id)sharedDefault { static UDPManager *manager = nil; @synchronized([self class]){ if(manager==nil){ manager = [[UDPManager alloc] init]; manager->_socketSender = SWL_INVALID_SOCKET; manager->_socketRecevier = SWL_INVALID_SOCKET; //_socketRecevier绑定的端口 manager->_localPort = 8899; //存储数据 NSMutableDictionary* LanlDevices = [[NSMutableDictionary alloc] initWithCapacity:0]; manager.LanlDevices = LanlDevices; manager->_isConditionOK = NO; } } return manager; } - (void)ScanLanDevice { //循环检测是否具备搜索条件 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [self verifySearchCondition]; }); //循环发送命令 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [self sendSearchCmdLoop]; }); //循环接收数据 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [self recviveDataLoop]; }); //循环删除超时的设备 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [self checkTimeoutLoop]; }); } -(void)CreateSender { SWL_socket_t sock = socket(AF_INET, SOCK_DGRAM, 0); if (SWL_INVALID_SOCKET == sock) { return; } int bOpt = 1; int ret = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const void*)&bOpt, sizeof(bOpt)); if (ret != -1) { _socketSender = sock; } } -(void)CreateRevicer { SWL_socket_t sock = socket(AF_INET, SOCK_DGRAM, 0); if (SWL_INVALID_SOCKET == sock) { return; } int ret; int nCount = 0; //写此while循环的原因:如果端口8899被占用,则绑定会失败,于是端口号+1000再绑定 while (nCount<20) { struct sockaddr_in addr; memset((char*)&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(_localPort); ret = bind(sock, (struct sockaddr*)&addr, sizeof(addr)); if (ret != -1) { break; } else { _localPort += 1000; usleep(10000); } nCount++; } if (ret != -1) { _socketRecevier = sock; } } -(void)verifySearchCondition { while (1) { //没有wifi时不搜索 NSString* ssid = [Utils currentWifiSSID]; //ap模式不搜索 int dwApContactID = [[AppDelegate sharedDefault]dwApContactID]; //后台运行不搜索 UIApplicationState iState = [UIApplication sharedApplication].applicationState; _isConditionOK = (ssid != nil && dwApContactID == 0 && iState != UIApplicationStateBackground); usleep(3*1000000); } } -(void)sendSearchCmdLoop { while (1) { if (!_isConditionOK) { usleep(3*1000000); continue; } // NSLog(@" === sendSearchCmdLoop"); if (_socketSender == SWL_INVALID_SOCKET) { [self CreateSender]; if (_socketSender == SWL_INVALID_SOCKET) { usleep(1*1000000); continue; } } struct sockaddr_in addr; memset((char*)&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_BROADCAST); addr.sin_port = htons(8899); char sendBuf = 1; const char* inBuffer = &sendBuf; long inLength = sizeof(char); int val = sendto(_socketSender, inBuffer, inLength, 0, (struct sockaddr*)&addr, sizeof(addr)); if (val == -1) { } usleep(3*1000000); } } -(void)recviveDataLoop { struct sockaddr_in addr_cli; int addr_cli_len = sizeof(addr_cli); char receiveBuffer[MAX_COMMAND_SIZE] = {0}; long bytes = 0; _isReceving = TRUE; //_isReceving while (_isReceving) { if (_socketRecevier == SWL_INVALID_SOCKET) { [self CreateRevicer]; if (_socketRecevier == SWL_INVALID_SOCKET) { usleep(1*1000000); continue; } } bytes = recvfrom(_socketRecevier, (char*)receiveBuffer, MAX_COMMAND_SIZE, 0, (struct sockaddr *)&addr_cli, (socklen_t *)&addr_cli_len); if (bytes == -1 || bytes == 0) { _isReceving = FALSE; } else if (bytes == 1) { usleep(1*100000); } else { int orderid = *(int*)(receiveBuffer); if(orderid == 2){ //局域网结果 char* szIP = inet_ntoa(addr_cli.sin_addr); int isSupportRtsp = *(int*)(&receiveBuffer[12]); isSupportRtsp = ((isSupportRtsp>>2)&1); int contactId = *(int*)(&receiveBuffer[16]); int type = *(int*)(&receiveBuffer[20]); int flag = *(int*)(&receiveBuffer[24]); if (type != 7 && type != 2 && type != 5) //只搜索ipc和npc和门铃 { continue; } NSDate* date = [[NSDate alloc]init]; double interval = [date timeIntervalSince1970]; LocalDevice *localDevice = [[LocalDevice alloc] init]; localDevice.contactId = [NSString stringWithFormat:@"%i",contactId]; localDevice.contactType = type; localDevice.flag = flag; localDevice.isSupportRtsp = isSupportRtsp; localDevice.address = [NSString stringWithFormat:@"%s", szIP]; localDevice.lanTimeInterval = interval; [self setContactWithID:localDevice contactID:[NSString stringWithFormat:@"%i",contactId]]; } } } } -(void)setContactWithID:(LocalDevice*)localDevice contactID:(NSString*)contactID { @synchronized(self) { [self.LanlDevices setObject:localDevice forKey:contactID]; } } -(void)checkTimeoutLoop { while (1) { @synchronized(self) { NSDate* date = [[NSDate alloc]init]; double interval = [date timeIntervalSince1970]; for(NSString *key in self.LanlDevices.allKeys) { LocalDevice *localDevice = [self.LanlDevices objectForKey:key]; if ((interval - localDevice.lanTimeInterval)>8.0) { [self.LanlDevices removeObjectForKey:key]; } } } usleep(3*1000000); } } -(NSArray*)getLanDevices { NSMutableArray *array = [NSMutableArray arrayWithCapacity:0]; @synchronized(self) { for(NSString *key in self.LanlDevices.allKeys) { LocalDevice *localDevice = [self.LanlDevices objectForKey:key]; [array addObject:localDevice]; } } return array; } -(void)clearData { @synchronized(self) { [self.LanlDevices removeAllObjects]; } } @end