I'm using Mobile snmp++ library (https://github.com/Zchander/mobile-snmp-plusplus/tree/master/Mobile%20SNMP%2B%2B) in iPhone app to scan devices using swift language.
The Mobile Snmp++ library is written in Objective-C and with Bridging header I'm able to use the this library in my swift project and it works perfectly.
I need to scan devices from particular range of ip address suppose 170.23.45.0 to 170.23.45.255. For this i'm using getoid function from XISMobile_SNMP_PP.mm (https://github.com/Zchander/mobile-snmp-plusplus/blob/master/Mobile%20SNMP%2B%2B/XISMobile_SNMP_PP.mm)
To get response from single ip address, it approximately takes 1-2 seconds per response.So to reduce the time, me using multithreading as suggested in the below link ( with maximum 20 of threads only at time since we are going to use the app in iphone) and it takes 20 seconds for complete scan from 0 to 255. I need to reduce this time to around 5 seconds. optimized way to search a device ip address within a range in iphone
Issue : Every time when search begins, getoid funtion opens socket and sends data and then gets response and closes socket. So can't we keep the socket open, scan all ip address and get it's respone and close the socket at last ? I need to reduce the search time from 20 seconds to 5 seconds so how can we do it in getoid function.
- (NSDictionary *)getOid:(NSString *)oid address:(NSString *)hostAddress snmpVersion:(uint)version remotePort:(NSNumber *)aPort withCommunity:(NSString *)community retry:(uint)retries timeout:(uint)timeout error:(NSError * __autoreleasing*)error { int status; uint l_retries; uint l_timeout; NSNumber *localPort; snmp_version snmpVersion = version1; OctetStr snmpCommunity([community UTF8String]); if ( aPort == nil ) { localPort = [NSNumber numberWithInteger:161]; } else localPort = aPort; if ( retries > 100 ) { l_retries = 100; } else l_retries = retries; if ( timeout < 100 ) { l_timeout = 100; } else if ( timeout > 500 ) { l_timeout = 500; } else l_timeout = timeout; switch ( version ) { case 1: snmpVersion = version1; break; case 2: snmpVersion = version2c; break; default: snmpVersion = version1; break; } // Generate a SNMP++ generic address UdpAddress udpAddress([hostAddress UTF8String]); // Check if it is a valid address, if we got an invalid address // we return a 'nil' dictionary and an error code if ( !udpAddress.valid() ) { *error = [self constructError:ERR_INVALID_DESTINATION]; #ifdef DEBUG NSLog(@"ERROR SNMPController (getOid:hostAddress:oid:snmpVersion:remotePort:withCommunity:retry:timeout:error:)"); NSLog(@"ERROR SNMP++ Invalid host address or IP: %@", hostAddress); NSLog(@"ERROR ===================="); #endif return nil; } // Check if we got a valid Oid, otherwise use sysDescr Oid localOid([oid UTF8String]); if ( !localOid.valid() ) { #ifdef DEBUG NSLog(@"ERROR SNMPController (getOid:hostAddress:oid:snmpVersion:remotePort:withCommunity:retry:timeout:error:)"); NSLog(@"ERROR SNMP++ We got an invalid Oid (%@), we are using sysDescr for now (.1.3.6.1.2.1.1.1.0)", oid); NSLog(@"ERROR ===================="); #endif Oid localOid("1.3.6.1.2.1.1.1.0"); } // Create the SNMP session Snmp snmp(status, 0, (udpAddress.get_ip_version() == Address::version_ipv6)); if ( status != SNMP_CLASS_SUCCESS ) { #ifdef DEBUG NSLog(@"ERROR SNMPController (getOid:hostAddress:oid:snmpVersion:remotePort:withCommunity:retry:timeout:error:)"); NSLog(@"ERROR SNMP++ Could not create session: %s", snmp.error_msg(status)); NSLog(@"ERROR ===================="); #endif *error = [self constructError:ERR_NO_SNMP_SESSION]; return nil; } // We are ready to build the SNMP++ object we need Pdu pdu; // construct a Pdu object Vb vb; // construct a Vb object vb.set_oid(localOid); // set the Oid portion of the Vb pdu += vb; // add the vb to the Pdu // Set the port udpAddress.set_port([localPort integerValue]); CTarget ctarget(udpAddress); // Make a target using the address ctarget.set_version(snmpVersion); // Set the SNMP version ctarget.set_retry(l_retries); // Set the number of retries ctarget.set_timeout(l_timeout); // Set the timeout for the request ctarget.set_readcommunity(snmpCommunity); // Set the read community name // Issue the request, in blocked mode #ifdef DEBUG NSLog(@"DEBUG SNMPController (getOid:hostAddress:oid:snmpVersion:remotePort:withCommunity:retry:timeout:error:)"); NSLog(@"DEBUG SNMP++ GET to %@ (oid: %@) with version %d on Port: %d using community %@ with retries %d and timeout %d", hostAddress, oid, version, [aPort integerValue], community, retries, timeout); NSLog(@"DEBUG SNMP++ What is the community we are sending.... %s", snmpCommunity.get_printable()); NSLog(@"DEBUG ===================="); #endif SnmpTarget *target; target = &ctarget; status = snmp.get(pdu, *target); NSMutableDictionary *resultsDict = [[NSMutableDictionary alloc] init]; if ( status == SNMP_CLASS_SUCCESS ) { pdu.get_vb(vb, 0); #ifdef DEBUG NSLog(@"DEBUG SNMPController (getOid:hostAddress:oid:snmpVersion:remotePort:withCommunity:retry:timeout:error:)"); NSLog(@"DEBUG SNMP++ -- Oid: %s", vb.get_printable_oid()); NSLog(@"DEBUG SNMP++ -- Value: %s", vb.get_printable_value()); #endif // Add the result(s) to the resultsDict [resultsDict setObject:[NSString stringWithUTF8String:vb.get_printable_value()] forKey:[NSString stringWithUTF8String:vb.get_printable_oid()]]; if ( (vb.get_syntax() == sNMP_SYNTAX_ENDOFMIBVIEW) || (vb.get_syntax() == sNMP_SYNTAX_NOSUCHINSTANCE) || (vb.get_syntax() == sNMP_SYNTAX_NOSUCHOBJECT)) { NSLog(@"ERROR SNMP++ Exception found: %lu", vb.get_syntax()); } else { NSLog(@"ERROR SNMP++ GET Error: %s (%d)", snmp.error_msg(status), status); } #ifdef DEBUG NSLog(@"DEBUG ===================="); #endif } // Make sure error is nil! *error = nil; return ( resultsDict != nil ) ? [NSDictionary dictionaryWithDictionary:resultsDict] : nil; }