Up

Overview of netclasses use

Authors

Andrew Ruder (aeruder@ksu.edu)

Version: Revision 1

Date: November 7, 2003

This file is an overview of the use of netclasses.

Copyright: (C) Andrew Ruder


Contents -

  1. Introduction
  2. Step 1: Create a server object
  3. Step 2: Create a port
  4. Step 3: Make it go!
  5. Conclusion

Introduction

This will hopefully explain the basic idea of creating a simple program with netclasses. In this file, I will take you through the creation of a simple server that echos all the data it receives back to the source.

Step 1: Create a server object

The first thing we need to do is create a class that will handle the connections. This class will need to implement the NetObject protocol.

Here is the interface for this class:

	// File EchoServ.h
	#import <netclasses/NetBase.h>
	#import <Foundation/NSObject.h>

	@class NSData;

	@interface EchoServ : NSObject <NetObject>
		{
			 id transport;
		}
		- connectionEstablished: (id <NetTransport>)aTransport;
		- dataReceived: (NSData *)data;
		- (id <NetTransport>)transport;
		- (void)connectionLost;
	@end
			

These methods are all callback methods. NetApplication will call these when appropriate. So now we just need to fill these in.

	//File EchoServ.m
	#import "EchoServ.h"
	#import <Foundation/NSData.h>

	@implementation EchoServ
			

The first method is connectionEstablished:. This method needs to retain the transport given to it. The transport is an object that actually handles the transportation of the data. In most cases, this method will also need to connect the object to the netclasses NetApplication system.

	- connectionEstablished: (id <NetTransport>)aTransport
	{
		 transport = [aTransport retain];
		 [[NetApplication sharedInstance] connectObject: self];
	}
			

The next method is dataReceived:. This will be called when new data is received, and the argument will hold the actual data received. In our program, we will want to write this data back to the transport immediately.

	- dataReceived: (NSData *)newData
	{
		 [transport writeData: newData];
	}
			

The next method we need to implement is transport. This one is pretty simple; just return the transport given to us in connectionEstablished:

	- (id <NetTransport>)transport
	{
		 return transport;
	}
			

Last but not least is connectionLost. This method will be called when the connection is lost. This can happen in three ways. First, an error could have occurred on the socket and it had to be closed. The second, the other side can simply have closed its side. The third, is quite simply that someone called [[NetApplication sharedInstance] disconnectObject:] on it.

	- (void)connectionLost
	{
		 [transport close];
		 [transport release];
		 transport = nil;
	}
	@end
			

And that is it for our object! Now let's set up the port to handle the creating of these objects.

Step 2: Create a port

Ok, we got our class all set up, so now we are going to setup a port that will receive connections and initialize EchoServ objects (created in Step 1) when new connections are received.

This is a pretty simple task (like everything in netclasses). Ok, let's write up the function and explain it.

	// File main.m
	
	#import "EchoServ.h"
	#import <netclasses/NetTCP.h>
	#import <Foundation/Foundation.h>

	void setup_port()
	{
		TCPPort *port; 

		port = [[TCPPort alloc] initOnPort: 0];
			

Ok, TCPPort is the class used to create a port handling connections on the TCP/IP protocol. initOnPort: takes the port number that you'd like to handle. If the port is 0, it will automatically find an empty port and bind itself to that.

Now we want to set the TCPPort we created to automatically create our class EchoServ when new connections are received. So:

		[port setNetObject: [EchoServ class]];
			

Ok, since we have no idea what port this has been created on, we better print that out. And after that we are done with the port, so we can go ahead and release it and return. When you create a TCPPort, it automatically connects itself with NetApplication, so don't worry about the object actually being deallocated.

		NSLog(@"Ready to go on port %d", [port port]);
		[x release];
		return;
	}
			

Ok, and that is all there is to creating the port! Now onto step 3.

Step 3: Make it go!

Ok, we've got our server object created and we've got the port ready to receive connections. What do we need to do now? Let's make it go!

	// File main.m (continued)
	int main(void)
	{
		 NSAutoreleasePool *arp;
		 arp = [[NSAutoreleasePool alloc] init];
		 
		 setup_port();
		 [[NSRunLoop currentRunLoop] run];
		 
		 [arp release];
		 return 0;
	}
			

Sorry to disappoint you! But that's it! netclasses will automatically handle any and all connections while the runloop is running. The runloop is a pretty integral part of just about any cocoa application (if you make a GUI program, the runloop is basically always going). Feel free to type up this program and compile it and test that it works! It does! In fact, this very program is almost exactly the same thing as the EchoServ example distributed with the standard netclasses distribution.

Conclusion

In conclusion, netclasses is very simple to use and quite usable for small applications and works well on large ones as well. The asynchronous design means that you don't have to worry about threads or any of the little details that you usually have to worry about on networking applications. Its easy to learn, easy to use, and can be used in a variety of applications. Enjoy!


Up