gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: "Modern" server socket programming?


From: Richard Frith-Macdonald
Subject: Re: "Modern" server socket programming?
Date: Tue, 8 Jan 2013 17:38:07 +0000

On 8 Jan 2013, at 16:55, Marcus Müller wrote:
> 
> SOLUTION?
> ==========
> 
> Searching for alternatives I've stumbled across GSSocketServerStream 
> (GSInetServerStream, …) which seems to be something that I could use, but 
> haven't found any code demonstrating how to use it. Does anybody have any 
> demo code/project as a starting point?

Look at the code in gnustep-base (NSURLProtocol.m) for an example of using the 
NSStream based stuff to make an HTTP (or HTTPS) request to a remote system.

I don't have any demo/example code for a server, but to show it, I chopped out 
the key bits of a larger program:

For acting as a server, here's a snippet of code from an SMTP server showing 
creation of the server listening socket:

    {
      NSHost    *h;
      NSString  *n;

      n = [profile valueForItem: @"RemoteHost"];
      if ([n length] == 0)
        {
          n = host;
        }
      if ([n length] == 0 || [n isEqual: @"-"])
        {
          n = @"localhost";
        }

      h = [NSHost hostWithName: n];
      if (h == nil)
        {
          mta.istream = nil;
          mta.ostream = nil;

          [self problem: @"Configuration (or DNS) error"
                 detail: @"Unable to find IP-address/domain-name: '%@'", n];
          [self shutdown];
        }
      else
        {
          NSString      *svc = service;

          ASSIGN(host, n);
          if ([svc intValue] <= 0)
            {
              svc = @"25";  // SMTP default port
              ASSIGN(service, svc);
            }
          [NSStream getStreamsToHost: h
                                port: [svc intValue]
                         inputStream: &mta.istream
                        outputStream: &mta.ostream];
          RETAIN(mta.istream);
          RETAIN(mta.ostream);
          if (mta.istream == nil || mta.ostream == nil)
            {
              [self problem: @"Data error"
                     detail: @"Unable to connect to %@:%@", n, svc];
              [self shutdown];
            }
        }

      [mta.istream setDelegate: self];
      [mta.ostream setDelegate: self];

      [mta.istream scheduleInRunLoop: [NSRunLoop currentRunLoop]
                             forMode: NSDefaultRunLoopMode];
      [mta.ostream scheduleInRunLoop: [NSRunLoop currentRunLoop]
                             forMode: NSDefaultRunLoopMode];
      [mta.istream open];
      [mta.ostream open];
    }

And here's some event handler code to accept an incoming connection:

- (void) stream: (NSStream*)aStream handleEvent: (NSStreamEvent)anEvent
{
  switch (anEvent) 
    {
      case NSStreamEventHasBytesAvailable: 
        {
          NSInputStream         *ip;
          NSOutputStream        *op;

          [serverStream acceptWithInputStream: &ip outputStream: &op];
          if (ip != nil && op != nil)
            {
              IncomingEmail     *o;

              o = [IncomingEmail alloc];
              o = [o initWithInStream: ip outStream: op];
              if (nil == incoming)
                {
                  incoming = [NSMutableArray new];
                }
              [incoming addObject: o];
              [o start];
              [o release];
            }
          break;
        }

      case NSStreamEventErrorOccurred: 
        {
          int   code = [[serverStream streamError] code];

          NSLog(@"Error on serverStream code is %d", code);
          [self closeServer];
          [self cmdQuit: 1];
          break;
        }  

      case NSStreamEventOpenCompleted: 
        break;

      case NSStreamEventHasSpaceAvailable: 
      case NSStreamEventEndEncountered: 
      default: 
        NSLog(@"Unexpected event %"PRIuPTR" on serverStream", anEvent);
        break;
    }
}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]