Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 04-19-2009, 10:41 AM   #1 (permalink)
Registered Member
 
Join Date: Oct 2008
Posts: 97
fordracerguy is on a distinguished road
Default Alternative to NSURLConnection?

My application is internet based. It queries a custom .php script to display it's data. I implemented NSURLConnection into a class of it's own to deal with my error correcting protocol. This class sends a message back to the delegate with success for fail. It works great but it has a memory leak. I've read all over that this memory leak in CFNetwork / httpWrFilterOpen is a bug in iPhone's operating system. Since my application has many screens that each requires the internet, it has a potential for a lot of leaks and I'm not okay with that.

Can I use AsyncSocket as a replacement for simple HTTP GET commands? Or are there any alternatives that do the same thing without using NSURLConnection?

Thanks!
Chris
fordracerguy is offline   Reply With Quote
Old 04-19-2009, 04:31 PM   #2 (permalink)
Former NeXTStep Developer
 
Join Date: Mar 2009
Posts: 997
FlyingDiver will become famous soon enough
Default

Quote:
Originally Posted by fordracerguy View Post
Can I use AsyncSocket as a replacement for simple HTTP GET commands? Or are there any alternatives that do the same thing without using NSURLConnection?

Thanks!
Chris
I have an application that uses ASyncSocket to talk to a device over the network. In my case, it's talking to a telnet server on the device, rather than an http server. It'll work, but it's much effort to get it all set up properly.

joe
FlyingDiver is offline   Reply With Quote
Old 04-20-2009, 05:13 PM   #3 (permalink)
Registered Member
 
Join Date: Oct 2008
Posts: 97
fordracerguy is on a distinguished road
Default

Quote:
Originally Posted by FlyingDiver View Post
I have an application that uses ASyncSocket to talk to a device over the network. In my case, it's talking to a telnet server on the device, rather than an http server. It'll work, but it's much effort to get it all set up properly.

joe
Would you mind sharing a bit of code on how you implemented it?
fordracerguy is offline   Reply With Quote
Old 04-20-2009, 05:22 PM   #4 (permalink)
Former NeXTStep Developer
 
Join Date: Mar 2009
Posts: 997
FlyingDiver will become famous soon enough
Default

Quote:
Originally Posted by fordracerguy View Post
Would you mind sharing a bit of code on how you implemented it?
The docs that come with the class files are actually pretty good. All my code was based on queuing multiple telnet commands to go to the server device. I don't think it would help you much. The real trick is deciding how you want to handle the asynchronicity of the interactions in your application.

Heck, here's about 95% of the code that uses the AsyncSocket class. If it helps, great.

Code:
#import <Foundation/Foundation.h>
#import <CoreFoundation/CFStream.h>
#import "AsyncSocket.h"
#include <fcntl.h>
#include <unistd.h>

@interface Controller : NSObject {
		
	NSMutableArray *cmdQueue;

	AsyncSocket *socket;
	int writesPending;
	long writeNum, readNum;
	BOOL connectionReady;
}

@property (readonly) NSMutableArray *cmdQueue;
@property (readonly) BOOL connectionReady;

-(id)initWithControllerIP:(NSString *) ipAddress;

-(void)getValue:(NSString *) name;
-(void)setValue:(NSString *) value forName: (NSString *) name;
-(void)sendCommand: (NSString *) cmd;

-(void)kickQueue;

-(void)onSocket:(AsyncSocket *) sock willDisconnectWithError:(NSError *) err;
-(void)onSocketDidDisconnect:(AsyncSocket *) sock;
-(void)onSocket:(AsyncSocket *) sock didConnectToHost:(NSString *) host port:(UInt16) port;
-(void)onSocket:(AsyncSocket *) sock didReadData:(NSData*) data withTag:(long) t;
-(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
@end

Code:
- (id)initWithControllerIP:(NSString *)ipAddress
{	
	// create queue for commands to send to controller
	
	if (!(cmdQueue = [[NSMutableArray alloc] init]))
		NSLog(@"Error creating Queue");
	
	writesPending = 0;
	connectionReady = NO;
	
	int port = 23;	// telnet port
	
	if (!(self = [super init]))
		return nil;
	
	// Create socket.
	socket = [[AsyncSocket alloc] initWithDelegate:self];
		
	// Set up stdin for non-blocking.
	if (fcntl (STDIN_FILENO, F_SETFL, O_NONBLOCK) == -1)
	{
		NSLog (@"Can't make STDIN non-blocking.");
		exit(1);
	}
		
	@try
	{
		NSError *err;
		
		if ([socket connectToHost:ipAddress onPort:port error:&err])
		{
			NSLog (@"Attempting connection to %@:%u.", ipAddress, port);
		}
		else
		{
			NSLog (@"Couldn't connect to %@:%u (%@).", ipAddress, port, err);
			return nil;
		}
	}
	@catch (NSException *exception)
	{
		NSLog ([exception reason]);
		return nil;
	}
	
	return self;
}

#pragma mark -
#pragma mark AsyncSocketDelegate methods

-(void) onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
{
	if (err != nil)
		NSLog (@"Socket will disconnect. Error domain %@, code %d (%@).",
			   [err domain], [err code], [err localizedDescription]);
	else
		NSLog (@"Socket will disconnect. No error.");

	connectionReady = NO;
}

-(void) onSocketDidDisconnect:(AsyncSocket *)sock
{
	NSLog (@"Socket disconnected.");
	connectionReady = NO;
	[[NSNotificationCenter defaultCenter] postNotificationName: @"iDSC_Disconnect" object: self userInfo: nil];
}

-(void) onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port;
{
	NSLog (@"Socket connected to %@:%u.", host, port);

	connectionReady = YES;	// can't use the controller until this is set
	
	NSData *newline = [@"\n" dataUsingEncoding:NSASCIIStringEncoding];
	[socket readDataToData:newline withTimeout:-1 tag: 0];		// clear any garbage from the connection, start reads
}

-(void) onSocket:(AsyncSocket *)sock didReadData:(NSData*)data withTag:(long)tag
{
	NSString *serverReply = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];

	// look at reply, and if it's a getvalue response ( name = "value"), post a Notification
	
	if ([serverReply rangeOfString:@"="].location != NSNotFound)
	{
		NSString *replyName = nil;
		NSString *replyValue = nil;
		NSScanner *scanner = [NSScanner scannerWithString:serverReply];
		
		// discard the device prompt

		[scanner scanUpToString:@"%" intoString:nil];
		[scanner scanUpToString:@" " intoString:nil];
		[scanner scanString:@" " intoString:nil];
		
		// first string (up to space) is the variable name
		[scanner scanUpToString:@" " intoString:&replyName];

		// skip = and first "
		[scanner scanUpToString:@"=" intoString:nil];
		[scanner scanUpToString:@"\"" intoString:nil];
		[scanner scanString:@"\"" intoString:nil];
		
		// up to next quote is value
		[scanner scanUpToString:@"\"" intoString:&replyValue];

		// if we got valid data, post it
		if (replyName && replyValue) {
			NSDictionary *update = [NSDictionary dictionaryWithObject:replyValue forKey:replyName];
			[[NSNotificationCenter defaultCenter] postNotificationName: @"iDSC_Update" object: self userInfo: update];
		}
	}
		
	[serverReply release];
	
	NSData *newline = [@"\n" dataUsingEncoding:NSASCIIStringEncoding];
	[socket readDataToData:newline withTimeout:-1 tag: 0];
}

// Whenever a write completes, decrement the count of writes outstanding, and kick the queue to see if there are more to send

- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag
{
	writesPending--;
	[self kickQueue];
}

- (void) kickQueue
{
	//	NSLog(@"kickQueue, writesPending = %d, cmdQueue count = %d", writesPending, [cmdQueue count]);
	
	while ((writesPending < 3) && ([cmdQueue count] > 0))
	{
		NSString *request = [cmdQueue objectAtIndex:0];
		NSData *data = [request dataUsingEncoding:NSASCIIStringEncoding];	
		[socket writeData:data withTimeout:-1 tag: 0];
		[cmdQueue removeObjectAtIndex:0];		
		writesPending++;
	}
}
FlyingDiver is offline   Reply With Quote
Old 04-20-2009, 05:44 PM   #5 (permalink)
m0s
Registered Member
 
Join Date: Mar 2009
Posts: 122
m0s is on a distinguished road
Default

Apparently
Code:
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
[[NSURLCache sharedURLCache] setDiskCapacity:0];
has stopped NSURLConnection leaking for some people.

I have yet to try it on my own leaking NSURLConnection.

I assume you just insert the snippet before your call,
but I may be very wrong.
m0s is offline   Reply With Quote
Old 04-20-2009, 05:48 PM   #6 (permalink)
Registered Member
 
Join Date: Oct 2008
Posts: 97
fordracerguy is on a distinguished road
Default

Quote:
Originally Posted by m0s View Post
Apparently
Code:
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
[[NSURLCache sharedURLCache] setDiskCapacity:0];
has stopped NSURLConnection leaking for some people.

I have yet to try it on my own leaking NSURLConnection.

I assume you just insert the snippet before your call,
but I may be very wrong.
I've tried these with no luck. It may have to do with the cache policy. I was just over on the devforums and some apple engineers said if it doesn't happen every connection, which it doesn't, don't worry about it. I guess it's fixed for good in the next OS.
fordracerguy is offline   Reply With Quote
Old 04-20-2009, 06:46 PM   #7 (permalink)
Registered Member
 
Join Date: Oct 2008
Posts: 97
fordracerguy is on a distinguished road
Default

Quote:
Originally Posted by FlyingDiver View Post
The docs that come with the class files are actually pretty good. All my code was based on queuing multiple telnet commands to go to the server device. I don't think it would help you much. The real trick is deciding how you want to handle the asynchronicity of the interactions in your application.

Heck, here's about 95% of the code that uses the AsyncSocket class. If it helps, great.
Thanks!! Very nice code indeed. I was just over at the apple devforums and there are numerous postings of my issue. Apple employees even said in more or less words to just ignore it for now, I guess it's fixed in the next OS...
fordracerguy is offline   Reply With Quote
Old 09-03-2009, 12:46 AM   #8 (permalink)
Registered Member
 
sumanth's Avatar
 
Join Date: Jul 2009
Location: India
Posts: 78
sumanth is on a distinguished road
Default

Hi FlyingDiver, need little clarification...you have called the read data function using

Code:
	[socket readDataToData:newline withTimeout:-1 tag: 0];		// clear any garbage from the connection, start reads
In my app, i need to write a data to the server, i have added the following code

Code:
-(void) onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port;{
	
	NSLog (@"Socket connected to %@:%u.", host, port);
	btnRecord.enabled=TRUE;
	connectionReady = YES;	// can't use the controller until this is set

	bytes=[NSData dataWithBytes:buf length:size];

	[socket writeData:bytes withTimeout:-1 tag: 0];

}
	
}

is that correct? bcause i tried above code and the server doesnt receive any data.
is there any other way?


thanks,
sumanth
sumanth is offline   Reply With Quote
Old 12-27-2010, 06:23 AM   #9 (permalink)
Registered Member
 
Join Date: Dec 2010
Posts: 2
madni.abbasi is on a distinguished road
Default iPhone App to send commands to telnet server

Hello FlyingDriver,

Can you please send me the complete code as there is no implementation of sendCommand and readResponse methods.

Please respond quickly because I have deadline....

Quote:
Originally Posted by FlyingDiver View Post
The docs that come with the class files are actually pretty good. All my code was based on queuing multiple telnet commands to go to the server device. I don't think it would help you much. The real trick is deciding how you want to handle the asynchronicity of the interactions in your application.

Heck, here's about 95% of the code that uses the AsyncSocket class. If it helps, great.

Code:
#import <Foundation/Foundation.h>
#import <CoreFoundation/CFStream.h>
#import "AsyncSocket.h"
#include <fcntl.h>
#include <unistd.h>

@interface Controller : NSObject {
		
	NSMutableArray *cmdQueue;

	AsyncSocket *socket;
	int writesPending;
	long writeNum, readNum;
	BOOL connectionReady;
}

@property (readonly) NSMutableArray *cmdQueue;
@property (readonly) BOOL connectionReady;

-(id)initWithControllerIP:(NSString *) ipAddress;

-(void)getValue:(NSString *) name;
-(void)setValue:(NSString *) value forName: (NSString *) name;
-(void)sendCommand: (NSString *) cmd;

-(void)kickQueue;

-(void)onSocket:(AsyncSocket *) sock willDisconnectWithError:(NSError *) err;
-(void)onSocketDidDisconnect:(AsyncSocket *) sock;
-(void)onSocket:(AsyncSocket *) sock didConnectToHost:(NSString *) host port:(UInt16) port;
-(void)onSocket:(AsyncSocket *) sock didReadData:(NSData*) data withTag:(long) t;
-(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
@end

Code:
- (id)initWithControllerIP:(NSString *)ipAddress
{	
	// create queue for commands to send to controller
	
	if (!(cmdQueue = [[NSMutableArray alloc] init]))
		NSLog(@"Error creating Queue");
	
	writesPending = 0;
	connectionReady = NO;
	
	int port = 23;	// telnet port
	
	if (!(self = [super init]))
		return nil;
	
	// Create socket.
	socket = [[AsyncSocket alloc] initWithDelegate:self];
		
	// Set up stdin for non-blocking.
	if (fcntl (STDIN_FILENO, F_SETFL, O_NONBLOCK) == -1)
	{
		NSLog (@"Can't make STDIN non-blocking.");
		exit(1);
	}
		
	@try
	{
		NSError *err;
		
		if ([socket connectToHost:ipAddress onPort:port error:&err])
		{
			NSLog (@"Attempting connection to %@:%u.", ipAddress, port);
		}
		else
		{
			NSLog (@"Couldn't connect to %@:%u (%@).", ipAddress, port, err);
			return nil;
		}
	}
	@catch (NSException *exception)
	{
		NSLog ([exception reason]);
		return nil;
	}
	
	return self;
}

#pragma mark -
#pragma mark AsyncSocketDelegate methods

-(void) onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
{
	if (err != nil)
		NSLog (@"Socket will disconnect. Error domain %@, code %d (%@).",
			   [err domain], [err code], [err localizedDescription]);
	else
		NSLog (@"Socket will disconnect. No error.");

	connectionReady = NO;
}

-(void) onSocketDidDisconnect:(AsyncSocket *)sock
{
	NSLog (@"Socket disconnected.");
	connectionReady = NO;
	[[NSNotificationCenter defaultCenter] postNotificationName: @"iDSC_Disconnect" object: self userInfo: nil];
}

-(void) onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port;
{
	NSLog (@"Socket connected to %@:%u.", host, port);

	connectionReady = YES;	// can't use the controller until this is set
	
	NSData *newline = [@"\n" dataUsingEncoding:NSASCIIStringEncoding];
	[socket readDataToData:newline withTimeout:-1 tag: 0];		// clear any garbage from the connection, start reads
}

-(void) onSocket:(AsyncSocket *)sock didReadData:(NSData*)data withTag:(long)tag
{
	NSString *serverReply = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];

	// look at reply, and if it's a getvalue response ( name = "value"), post a Notification
	
	if ([serverReply rangeOfString:@"="].location != NSNotFound)
	{
		NSString *replyName = nil;
		NSString *replyValue = nil;
		NSScanner *scanner = [NSScanner scannerWithString:serverReply];
		
		// discard the device prompt

		[scanner scanUpToString:@"%" intoString:nil];
		[scanner scanUpToString:@" " intoString:nil];
		[scanner scanString:@" " intoString:nil];
		
		// first string (up to space) is the variable name
		[scanner scanUpToString:@" " intoString:&replyName];

		// skip = and first "
		[scanner scanUpToString:@"=" intoString:nil];
		[scanner scanUpToString:@"\"" intoString:nil];
		[scanner scanString:@"\"" intoString:nil];
		
		// up to next quote is value
		[scanner scanUpToString:@"\"" intoString:&replyValue];

		// if we got valid data, post it
		if (replyName && replyValue) {
			NSDictionary *update = [NSDictionary dictionaryWithObject:replyValue forKey:replyName];
			[[NSNotificationCenter defaultCenter] postNotificationName: @"iDSC_Update" object: self userInfo: update];
		}
	}
		
	[serverReply release];
	
	NSData *newline = [@"\n" dataUsingEncoding:NSASCIIStringEncoding];
	[socket readDataToData:newline withTimeout:-1 tag: 0];
}

// Whenever a write completes, decrement the count of writes outstanding, and kick the queue to see if there are more to send

- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag
{
	writesPending--;
	[self kickQueue];
}

- (void) kickQueue
{
	//	NSLog(@"kickQueue, writesPending = %d, cmdQueue count = %d", writesPending, [cmdQueue count]);
	
	while ((writesPending < 3) && ([cmdQueue count] > 0))
	{
		NSString *request = [cmdQueue objectAtIndex:0];
		NSData *data = [request dataUsingEncoding:NSASCIIStringEncoding];	
		[socket writeData:data withTimeout:-1 tag: 0];
		[cmdQueue removeObjectAtIndex:0];		
		writesPending++;
	}
}

Last edited by madni.abbasi; 01-11-2011 at 03:05 PM.
madni.abbasi is offline   Reply With Quote
Old 01-12-2011, 08:11 AM   #10 (permalink)
Registered Member
 
Join Date: Dec 2010
Posts: 2
madni.abbasi is on a distinguished road
Default

Hi All,

Is there anybody who have working application sending command to telnet server ?

I need little clarification if possible.
madni.abbasi is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 322
7 members and 315 guests
blueorb, guusleijsten, jbro, Kryckter, mer10, n00b, SLIC
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,649
Threads: 94,113
Posts: 402,880
Top Poster: BrianSlick (7,990)
Welcome to our newest member, Anwerbl
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 08:59 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0