home *** CD-ROM | disk | FTP | other *** search
- //
- // Listing3.m
- // SchmoozingExamples
- //
- // Created by garrison on Fri Apr 20 2001.
- // Copyright (c) 2001 Standard Orbit Software, LLC. All rights reserved.
- //
- // Permission is granted to use this code for any purpose, at your own risk.
- // No warranties are expressed or implied.
-
- #import <Foundation/Foundation.h>
- #import <OmniNetworking/OmniNetworking.h>
-
- /* An Algorithm for an Iterative Server [Comer93]
- 1) Create a socket and bind it to a well known port number for the server being offered.
- 2) Establish a listener on the socket for incoming connections.
- 3) Accept the next connection request on the socket and obtain a new socket for the connection.
- 4) Repeatedly read the socket for a client request, generate a response, and send the reply back according to the application’s protocol.
- 5) When finished handling a particular client request, close the connection and go back to step 3, accepting the next connection.
- */
-
- int main (int argc, const char * argv[])
- {
- // An Iterative TCP Server
-
- unsigned short serverPort = 1701;
- ONTCPSocket *serverSocket;
- NSAutoreleasePool *mainPool;
-
- mainPool = [[NSAutoreleasePool alloc] init];
-
- NS_DURING {
- serverSocket = [ONTCPSocket tcpSocket];
- // Step 1. Allocate a socket
-
- [serverSocket startListeningOnLocalPort: serverPort allowingAddressReuse:YES];
- // Step 2. Start listening on it.
- }
- NS_HANDLER {
- // tcpSocket: could throw ONInternetSocketConnectFailedExceptionName if a
- // a socket can't be allocated.
- // startListeningOnLocalPort throws
- // ONTCPSocketListenFailedExceptionName if a listener can't be established.
-
- NSLog(@"%@ raised during server init: %@", [localException name],
- localException);
- exit(1);
- }
- NS_ENDHANDLER
-
- do {
- ONTCPSocket *connectionSocket = nil;
- NSMutableData *clientData = nil;
- NSString *clientRequest = nil;
- NSAutoreleasePool *loopPool = nil;
-
- loopPool = [[NSAutoreleasePool alloc] init];
- NS_DURING {
- NSLog(@"Listening for the next connection");
- connectionSocket = [serverSocket acceptConnectionOnNewSocket];
- // Step 3. Accept the incoming connection.
- }
- NS_HANDLER {
- // acceptConnectionOnNewSocket throws
- // ONTCPSocketAcceptFailedExceptionName if an error occurs.
-
- NSLog(@"%@ raised while waiting for connection: %@",
- [localException name], localException);
-
- break;
- // Break out of the server loop and exit.
- }
- NS_ENDHANDLER
-
-
- NS_DURING {
- // Step 4. Interact with the client.
-
- clientData = [NSMutableData data];
- [clientData appendData:[connectionSocket readData]];
- while ( [connectionSocket isReadable] )
- [clientData appendData:[connectionSocket readData]];
- // Read in the client's request. The readData: will block until the
- // client sends something. It'll read up to 2048 bytes in one shot, although
- // you can adjust the size of the readbuffer with the setReadBufferSize: method.
- // If the client's requests is larger than that, you have to loop until you've
- // read the whole thing. After the first read, loop and check the socket for
- // more data. If there is some, keep readingl; otherwise, you're done.
-
- clientRequest = [[[NSString alloc] initWithData:clientData
- encoding:NSASCIIStringEncoding] autorelease];
- // Convert the client's request into an ASCII string so that we can echo it back.
-
- [connectionSocket writeFormat:@"You sent me: %@", clientRequest];
- [connectionSocket writeFormat:@"I'm sending you this: %@",
- [clientRequest uppercaseString]];
- // Generate a reply and send it back to the client.
-
- [loopPool release];
- // Step 5. Close the connection and listening for the next connection.
- // Releasing the pool will release our socket, which causes it to be
- // gracefully closed.
- }
- NS_HANDLER {
- // ONTCPSocket's I/O methods can throw...
- // ONInternetSocketUserAbortExceptionName, if the connection is
- // aborted (via abortSocket:), or
- // ONInternetSocketWouldBlockExceptionName, if the socket is in non-blocking
- // mode and a read or write would have caused the socket to block.
- // ONInternetSocketReadFailedExceptionName if the read fails.
- // ONInternetSocketWriteFailedExceptionName if the write fails.
-
- NSLog(@"%@ raised during server interaction with client: %@",
- [localException name], localException);
-
- [loopPool release];
-
- break;
- // Exit the server loop on error.
- }
- NS_ENDHANDLER
-
- } while (1);
-
- [mainPool release];
-
-
- return(0);
- exit(0);
- }