home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2001 / MacHack 2001.toast / pc / Papers / Garrison / Code / SchmoozingExamples / Listing3.m < prev    next >
Encoding:
Text File  |  2001-06-23  |  5.2 KB  |  130 lines

  1. //
  2. //  Listing3.m
  3. //  SchmoozingExamples
  4. //
  5. //  Created by garrison on Fri Apr 20 2001.
  6. //  Copyright (c) 2001 Standard Orbit Software, LLC. All rights reserved.
  7. //
  8. //  Permission is granted to use this code for any purpose, at your own risk.
  9. //  No warranties are expressed or implied.
  10.  
  11. #import <Foundation/Foundation.h>
  12. #import <OmniNetworking/OmniNetworking.h>
  13.  
  14. /* An Algorithm for an Iterative Server [Comer93]
  15. 1) Create a socket and bind it to a well known port number for the server being offered.
  16. 2) Establish a listener on the socket for incoming connections.
  17. 3) Accept the next connection request on the socket and obtain a new socket for the connection.
  18. 4) Repeatedly read the socket for a client request, generate a response, and send the reply back according to the application’s protocol.
  19. 5) When finished handling a particular client request, close the connection and go back to step 3, accepting the next connection.
  20. */
  21.  
  22. int main (int argc, const char * argv[])
  23. {
  24.     // An Iterative TCP Server
  25.     
  26.     unsigned short serverPort = 1701;
  27.     ONTCPSocket *serverSocket;
  28.     NSAutoreleasePool *mainPool;
  29.     
  30.     mainPool = [[NSAutoreleasePool alloc] init];
  31.     
  32.     NS_DURING {
  33.         serverSocket = [ONTCPSocket tcpSocket];
  34.         // Step 1.  Allocate a socket
  35.         
  36.         [serverSocket startListeningOnLocalPort: serverPort allowingAddressReuse:YES];
  37.         // Step 2.  Start listening on it.
  38.     }
  39.     NS_HANDLER {
  40.         // tcpSocket: could throw ONInternetSocketConnectFailedExceptionName if a
  41.         // a socket can't be allocated.
  42.         // startListeningOnLocalPort throws
  43.         // ONTCPSocketListenFailedExceptionName if a listener can't be established.
  44.         
  45.         NSLog(@"%@ raised during server init: %@", [localException name],
  46.             localException);
  47.         exit(1);
  48.     }
  49.     NS_ENDHANDLER
  50.     
  51.     do {
  52.         ONTCPSocket *connectionSocket = nil;
  53.         NSMutableData *clientData = nil;
  54.         NSString *clientRequest = nil;
  55.         NSAutoreleasePool *loopPool = nil;
  56.  
  57.         loopPool = [[NSAutoreleasePool alloc] init];
  58.         NS_DURING {
  59.             NSLog(@"Listening for the next connection");
  60.             connectionSocket = [serverSocket acceptConnectionOnNewSocket];
  61.             // Step 3.  Accept the incoming connection.
  62.         }
  63.         NS_HANDLER {
  64.             // acceptConnectionOnNewSocket throws
  65.             // ONTCPSocketAcceptFailedExceptionName if an error occurs.
  66.             
  67.             NSLog(@"%@ raised while waiting for connection: %@",
  68.                 [localException name], localException);
  69.                 
  70.             break;
  71.             // Break out of the server loop and exit.
  72.         }
  73.         NS_ENDHANDLER
  74.         
  75.         
  76.         NS_DURING {
  77.             // Step 4.  Interact with the client.
  78.             
  79.             clientData = [NSMutableData data];
  80.             [clientData appendData:[connectionSocket readData]];
  81.             while ( [connectionSocket isReadable] )
  82.                 [clientData appendData:[connectionSocket readData]];
  83.             // Read in the client's request.  The readData: will block until the
  84.             // client sends something.  It'll read up to 2048 bytes in one shot, although
  85.             // you can adjust the size of the readbuffer with the setReadBufferSize: method.  
  86.             // If the client's requests is larger than that, you have to loop until you've 
  87.             // read the whole thing.  After the first read, loop and check the socket for
  88.             // more data.  If there is some, keep readingl; otherwise, you're done.
  89.                         
  90.             clientRequest = [[[NSString alloc] initWithData:clientData
  91.                                     encoding:NSASCIIStringEncoding] autorelease];
  92.             // Convert the client's request into an ASCII string so that we can echo it back.
  93.             
  94.             [connectionSocket writeFormat:@"You sent me: %@", clientRequest];
  95.             [connectionSocket writeFormat:@"I'm sending you this: %@", 
  96.                                         [clientRequest uppercaseString]];
  97.             // Generate a reply and send it back to the client.
  98.             
  99.             [loopPool release];
  100.             // Step 5.  Close the connection and listening for the next connection.
  101.             // Releasing the pool will release our socket, which causes it to be
  102.             // gracefully closed.
  103.         }
  104.         NS_HANDLER {
  105.             // ONTCPSocket's I/O methods can throw...
  106.             // ONInternetSocketUserAbortExceptionName, if the connection is
  107.             //         aborted (via abortSocket:), or
  108.             // ONInternetSocketWouldBlockExceptionName, if the socket is in non-blocking
  109.             //         mode and a read or write would have caused the socket to block.
  110.             // ONInternetSocketReadFailedExceptionName if the read fails.
  111.             // ONInternetSocketWriteFailedExceptionName if the write fails.
  112.             
  113.             NSLog(@"%@ raised during server interaction with client: %@",
  114.                 [localException name], localException);
  115.                 
  116.             [loopPool release];
  117.             
  118.             break;
  119.             // Exit the server loop on error.
  120.         }
  121.         NS_ENDHANDLER
  122.         
  123.     } while (1);
  124.     
  125.     [mainPool release];
  126.     
  127.     
  128.     return(0);
  129.     exit(0);
  130. }