jens@0: // jens@0: // TCPListener.m jens@0: // MYNetwork jens@0: // jens@0: // Created by Jens Alfke on 5/10/08. jens@0: // Copyright 2008 Jens Alfke. All rights reserved. jens@0: jens@0: #import "TCPEndpoint.h" jens@0: @class TCPConnection, IPAddress; jens@0: @protocol TCPListenerDelegate; jens@0: jens@0: jens@0: /** Generic TCP-based server that listens for incoming connections on a port. jens@0: For each incoming connection, it creates an instance of (a subclass of) the generic TCP jens@0: client class TCPClient. The -connectionClass property lets you customize which subclass jens@0: to use. jens@0: TCPListener supports Bonjour advertisements for the service, and automatic port renumbering jens@0: if there are conflicts. */ jens@0: @interface TCPListener : TCPEndpoint jens@0: { jens@0: @private jens@0: uint16_t _port; jens@0: BOOL _pickAvailablePort; jens@0: BOOL _useIPv6; jens@0: CFSocketRef _ipv4socket; jens@0: CFSocketRef _ipv6socket; jens@0: jens@0: NSString *_bonjourServiceType, *_bonjourServiceName; jens@0: NSNetService *_netService; jens@0: NSDictionary *_bonjourTXTRecord; jens@0: BOOL _bonjourPublished; jens@0: NSInteger /*NSNetServicesError*/ _bonjourError; jens@0: jens@0: Class _connectionClass; jens@0: } jens@0: jens@0: /** Initializes a new TCPListener that will listen on the given port when opened. */ jens@0: - (id) initWithPort: (UInt16)port; jens@0: jens@0: /** The subclass of TCPConnection that will be instantiated. */ jens@0: @property Class connectionClass; jens@0: jens@0: @property (assign) id delegate; jens@0: jens@0: /** Should the server listen for IPv6 connections (on the same port number)? Defaults to NO. */ jens@0: @property BOOL useIPv6; jens@0: jens@0: /** The port number to listen on. jens@0: If the pickAvailablePort property is enabled, this value may be updated after the server opens jens@0: to reflect the actual port number being used. */ jens@0: @property uint16_t port; jens@0: jens@0: /** Should the server pick a higher port number if the desired port is already in use? jens@0: Defaults to NO. If enabled, the port number will be incremented until a free port is found. */ jens@0: @property BOOL pickAvailablePort; jens@0: jens@0: /** Opens the server. You must call this after configuring all desired properties (property jens@0: changes are ignored while the server is open.) */ jens@0: - (BOOL) open: (NSError **)error; jens@0: jens@0: - (BOOL) open; jens@0: jens@0: /** Closes the server. */ jens@0: - (void) close; jens@0: jens@0: /** Is the server currently open? */ jens@0: @property (readonly) BOOL isOpen; jens@0: jens@0: jens@0: #pragma mark BONJOUR: jens@0: jens@0: /** The Bonjour service type to advertise. Defaults to nil; setting it implicitly enables Bonjour. jens@0: The value should look like e.g. "_http._tcp."; for details, see the NSNetService documentation. */ jens@0: @property (copy) NSString *bonjourServiceType; jens@0: jens@0: /** The Bonjour service name to advertise. Defaults to nil, meaning that a default name will be jens@0: automatically generated if Bonjour is enabled (by setting -bonjourServiceType). */ jens@0: @property (copy) NSString *bonjourServiceName; jens@0: jens@0: /** The dictionary form of the Bonjour TXT record: metadata about the service that can be browsed jens@0: by peers. Changes to this dictionary will be pushed in near-real-time to interested peers. */ jens@0: @property (copy) NSDictionary *bonjourTXTRecord; jens@0: jens@0: /** Is this service currently published/advertised via Bonjour? */ jens@0: @property (readonly) BOOL bonjourPublished; jens@0: jens@0: /** Current error status of Bonjour service advertising. See NSNetServicesError for error codes. */ jens@0: @property (readonly) NSInteger /*NSNetServicesError*/ bonjourError; jens@0: jens@0: jens@0: @end jens@0: jens@0: jens@0: jens@0: #pragma mark - jens@0: jens@0: /** The delegate messages sent by TCPListener. */ jens@0: @protocol TCPListenerDelegate jens@0: jens@0: - (void) listener: (TCPListener*)listener didAcceptConnection: (TCPConnection*)connection; jens@0: jens@0: @optional jens@0: - (void) listenerDidOpen: (TCPListener*)listener; jens@0: - (void) listener: (TCPListener*)listener failedToOpen: (NSError*)error; jens@0: - (void) listenerDidClose: (TCPListener*)listener; jens@0: - (BOOL) listener: (TCPListener*)listener shouldAcceptConnectionFrom: (IPAddress*)address; jens@0: @end