Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

deksa

macrumors newbie
Original poster
Feb 2, 2010
3
0
Hi there,

I ran a java server using this tutorial: http://java.sun.com/docs/books/tutorial/networking/sockets/clientServer.html
It works fine with java clients.

Then I read the documentation on iPhone socket networking and the www and I came up with the following code:
Code:
- (IBAction)togglePower:(id)sender
{	
	//http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/Streams/Articles/NetworkStreams.html#//apple_ref/doc/uid/20002277
	//
	//NSString *urlStr = [[NSString alloc] initWithString:@"//localhost:4444"];
	NSString *urlStr = [[NSString alloc] initWithString:@"//xxx.yyy.z.kkk:4444"];
	
	//if (host != nil)
	if (![urlStr isEqualToString:@""])
	{	
		NSURL *website = [NSURL URLWithString:urlStr];
		
		if (!website) {
			NSLog(@"%@ is not a valid URL");
			return;
		}
		
		// iStream and oStream are instance variables
		CFReadStreamRef readStream;
		CFWriteStreamRef writeStream;
		CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)[website host], 80, &readStream, &writeStream);
		iStream = (NSInputStream *)readStream;
                oStream = (NSOutputStream *)writeStream;
		
		
		//iStream is instance var of NSSInputStream
		[iStream retain];
		[iStream setDelegate:self];
		[iStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
		[iStream open];
		
		//oStream is instance var of NSSOutputStream
		[oStream retain];
		[oStream setDelegate:self];
		[oStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
		[oStream open];		
		
		NSError *streamError;
		streamError = [iStream streamError];
		streamError = [oStream streamError];
		
		NSStreamStatus streamStatus;
		streamStatus = [iStream streamStatus];
		streamStatus = [oStream streamStatus];
	}
}

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent
{
	NSString *io;
	if (theStream == iStream) io = @">>";
	else io = @"<<";
	
	NSString *event;
	switch (streamEvent)
	{
		case NSStreamEventNone:
			event = @"NSStreamEventNone";
			break;
		case NSStreamEventOpenCompleted:
			event = @"NSStreamEventOpenCompleted";
			break;
		case NSStreamEventHasBytesAvailable:
			event = @"NSStreamEventHasBytesAvailable";
			if (theStream == iStream)
			{
				//read data
				uint8_t buffer[1024];
				int len;
				while ([iStream hasBytesAvailable])
				{
					len = [iStream read:buffer maxLength:sizeof(buffer)];
					if (len > 0)
					{
						NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
						if (nil != output)
						{
							NSLog(@"%@ : %@", io, output);
						}
					}
				}
			}
			break;
		case NSStreamEventHasSpaceAvailable:
			event = @"NSStreamEventHasSpaceAvailable";
			if (theStream == oStream)
			{
				//send data
				uint8_t buffer[] = "sendir,2:1,1,40000,1,1,96,22,49,22,24,23,49,22,24,23,49,22,24,23,24,23,49,22,24,23,24,23,24,23,24,1025,96,22,49,22,24,23,49,22,24,23,49,22,24,23,24,23,49,22,24,23,24,23,24,23,24,1025,96,22,49,22,24,23,49,22,24,23,49,22,24,23,24,23,49,22,24,23,24,23,24,23,24,1025,96,22,49,22,24,23,49,22,24,23,49,22,24,23,24,23,49,22,24,23,24,23,24,23,24,1025,96,22,49,22,24,23,49,22,24,23,49,22,24,23,24,23,49,22,24,23,24,23,24,23,24,1987\r";				
				int len;
				
				len = [oStream write:buffer maxLength:sizeof(buffer)];
				
				if (len > 0)
				{
					NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
					NSLog(@"%@ : %@", io, output);
					[oStream close];
				}
			}
			break;
		case NSStreamEventErrorOccurred:
			event = @"NSStreamEventErrorOccurred";
			break;
		case NSStreamEventEndEncountered:
			event = @"NSStreamEventEndEncountered";
            [theStream close];
            [theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            [theStream release];
            theStream = nil;
			
			break;
		default:
			event = @"** Unknown";
	}
	
	NSLog(@"%@ : %@", io, event);
}

Then I run the java server (the server is waiting on the accept command). Than ran the iPhone application. The iPhone client creates the NSURL with the mac's address and port (I checked these from the terminal). It doesn't seem to open a new thread on the server side, like it did with the java clients (it doesn't unblock the server's accept() command).

In the log file I get this:
Attaching to process 210.
Pending breakpoint 1 - ""NetworkTestAppDelegate.m:94" resolved
Pending breakpoint 2 - ""NetworkTestAppDelegate.m:27" resolved
Current language: auto; currently objective-c
(gdb) continue
2010-02-02 09:19:01.279 NetworkTest[210:207] >> : NSStreamEventOpenCompleted
2010-02-02 09:19:01.280 NetworkTest[210:207] << : NSStreamEventOpenCompleted
2010-02-02 09:19:01.280 NetworkTest[210:207] << : sendir,2:1,1,40000,1,1,96,22,49,22,24,23,49,22,24,23,49,22,24,23,24,23,49,22,24,23,24,23,24,23,24,1025,96,22,49,22,24,23,49,22,24,23,49,22,24,23,24,23,49,22,24,23,24,23,24,23,24,1025,96,22,49,22,24,23,49,22,24,23,49,22,24,23,24,23,49,22,24,23,24,23,24,23,24,1025,96,22,49,22,24,23,49,22,24,23,49,22,24,23,24,23,49,22,24,23,24,23,24,23,24,1025,96,22,49,22,24,23,49,22,24,23,49,22,24,23,24,23,49,22,24,23,24,23,24,23,24,1987
2010-02-02 09:19:01.281 NetworkTest[210:207] << : NSStreamEventHasSpaceAvailable
(gdb) continue
2010-02-02 09:19:57.289 NetworkTest[210:207] >> : NSStreamEventHasBytesAvailable
2010-02-02 09:19:57.290 NetworkTest[210:207] >> : NSStreamEventEndEncountered
kill
quit

The Debugger has exited with status 0.

If I don't run the java server, I get the same thing (the log describes the same process).

I wanted to see if they will communicate. My way of thinking is that the client as soon it connects should receive some characters (like "Knock knock!" or something like this "@#$#H@HKL" if the encoding is wrong), but the client doesn't receive anything (len==0) and exits the case.

QUESTION:
Am I doing something wrong here?
I don't understand why they can't exchange bytes...
How can I connect them?

Your opinions would be appreciated!
Kind Regards,
Deksa
 
Why not use tomcat with java? and send things up and down in ssl over the POST? For most things this is more than fine.
 
Why not use tomcat with java? and send things up and down in ssl over the POST? For most things this is more than fine.

Hi,

because I need this to go through TCP.
Can you tell me if you see some hole in the logic?

Thanks for you reply!
Deksa
 
POST goes over HTTP, which in turn goes over TCP.

http://en.wikipedia.org/wiki/OSI_model

Hi,

I really don't need the overhead from HTTP. I just need a communication with TCP sockets.
If there is no solution to this using just TCP communication I would do it with HTTP, but if someone knows how to do this, it would be great if he can share that here.

Thanks again,
Deksa
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.