Initial commit
This commit is contained in:
@@ -0,0 +1,286 @@
|
||||
//
|
||||
// UDPManager.m
|
||||
// 2cu
|
||||
//
|
||||
// Created by wutong on 15-1-13.
|
||||
// Copyright (c) 2015年 guojunyi. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
#import "UDPManager.h"
|
||||
#import <sys/socket.h>
|
||||
#import <netinet/in.h>
|
||||
#import <arpa/inet.h>
|
||||
#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
|
||||
Reference in New Issue
Block a user