TCP/TCPConnection.h
author morrowa
Tue Jun 23 12:46:40 2009 -0700 (2009-06-23)
changeset 53 e9f209a24d53
parent 26 cb9cdf247239
permissions -rw-r--r--
Connections opened by listeners now close correctly.
     1 //
     2 //  TCPConnection.h
     3 //  MYNetwork
     4 //
     5 //  Created by Jens Alfke on 5/18/08.
     6 //  Copyright 2008 Jens Alfke. All rights reserved.
     7 //
     8 
     9 #import "TCPEndpoint.h"
    10 #import <Security/Security.h>
    11 @class IPAddress;
    12 @class TCPReader, TCPWriter, TCPListener, MYBonjourService;
    13 @protocol TCPConnectionDelegate;
    14 
    15 
    16 typedef enum {
    17     kTCP_Disconnected = -1,
    18     kTCP_Closed,
    19     kTCP_Opening,
    20     kTCP_Open,
    21     kTCP_Closing
    22 } TCPConnectionStatus;
    23 
    24 
    25 /** A generic class that manages a TCP socket connection.
    26     It creates a TCPReader and a TCPWriter to handle I/O.
    27     TCPConnection itself mostly deals with SSL setup and opening/closing the socket.
    28     (The SSL related methods are inherited from TCPEndpoint.) */
    29 @interface TCPConnection : TCPEndpoint
    30 {
    31     @private
    32     TCPListener *_server;
    33     IPAddress *_address;
    34     BOOL _isIncoming, _checkedPeerCert;
    35     TCPConnectionStatus _status;
    36     TCPReader *_reader;
    37     TCPWriter *_writer;
    38     NSError *_error;
    39     NSTimeInterval _openTimeout;
    40 }
    41 
    42 /** Initializes a TCPConnection to the given IP address.
    43     Afer configuring settings, you should call -open to begin the connection. */
    44 - (id) initToAddress: (IPAddress*)address;
    45 
    46 /** Initializes a TCPConnection to the given NSNetService's address and port.
    47     If the service's address cannot be resolved, nil is returned. */
    48 - (id) initToNetService: (NSNetService*)service;
    49 
    50 /** Initializes a TCPConnection to the given MYBonjourService's address and port.
    51     If the service's address cannot be resolved, nil is returned. */
    52 - (id) initToBonjourService: (MYBonjourService*)service;
    53 
    54 /** Initializes a TCPConnection from an incoming TCP socket.
    55     You don't usually need to call this; TCPListener does it automatically. */
    56 - (id) initIncomingFromSocket: (CFSocketNativeHandle)socket listener: (TCPListener*)listener;
    57 
    58 /** Timeout for waiting to open a connection. (Default is zero, meaning the OS default timeout.) */
    59 @property NSTimeInterval openTimeout;
    60 
    61 /** The delegate object that will be called when the connection opens, closes or receives messages. */
    62 @property (assign) id<TCPConnectionDelegate> delegate;
    63 
    64 /** The certificate(s) of the connected peer, if this connection uses SSL.
    65     The items in the array are SecCertificateRefs; use the Keychain API to work with them. */
    66 @property (readonly) NSArray *peerSSLCerts;
    67 
    68 /** Connection's current status */
    69 @property (readonly) TCPConnectionStatus status;
    70 
    71 /** Opens the connection. This happens asynchronously; wait for a delegate method to be called.
    72     You don't need to open incoming connections received via a TCPListener. */
    73 - (void) open;
    74 
    75 /** Closes the connection, after waiting for all in-progress messages to be sent or received.
    76     This happens asynchronously; wait for a delegate method to be called.*/
    77 - (void) close;
    78 
    79 /** Closes the connection, like -close, but if it hasn't closed by the time the timeout
    80     expires, it will disconnect the socket. */
    81 - (void) closeWithTimeout: (NSTimeInterval)timeout;
    82 
    83 /** Closes all open TCPConnections. */
    84 + (void) closeAllWithTimeout: (NSTimeInterval)timeout;
    85 
    86 /** Blocks until all open TCPConnections close. You should call +closeAllWithTimeout: first. */
    87 + (void) waitTillAllClosed;
    88 
    89 /** The IP address of the other peer. */
    90 @property (readonly,retain) IPAddress *address;
    91 
    92 /** The TCPListener that created this incoming connection, or nil */
    93 @property (readonly) TCPListener *server;
    94 
    95 /** Is this an incoming connection, received via a TCPListener? */
    96 @property (readonly) BOOL isIncoming;
    97 
    98 /** The fatal error, if any, 
    99     that caused the connection to fail to open or to disconnect unexpectedly. */
   100 @property (readonly) NSError *error;
   101 
   102 /** The actual security level of this connection. 
   103     Value is nil or one of the security level constants from NSStream.h,
   104     such as NSStreamSocketSecurityLevelTLSv1. */
   105 @property (readonly) NSString* actualSecurityLevel;
   106 
   107 
   108 @property (readonly) TCPReader *reader;
   109 @property (readonly) TCPWriter *writer;
   110 
   111 
   112 // protected:
   113 - (Class) readerClass;
   114 - (Class) writerClass;
   115 - (void) _beginClose;
   116 - (void) _unclose;
   117 
   118 @end
   119 
   120 
   121 
   122 /** The delegate messages sent by TCPConnection.
   123     All methods are optional. */
   124 @protocol TCPConnectionDelegate <NSObject>
   125 @optional
   126 /** Called after the connection successfully opens. */
   127 - (void) connectionDidOpen: (TCPConnection*)connection;
   128 /** Called after the connection fails to open due to an error. */
   129 - (void) connection: (TCPConnection*)connection failedToOpen: (NSError*)error;
   130 /** Called when the identity of the peer is known, if using an SSL connection and the SSL
   131     settings say to check the peer's certificate.
   132     This happens, if at all, after the -connectionDidOpen: call. */
   133 - (BOOL) connection: (TCPConnection*)connection authorizeSSLPeer: (SecCertificateRef)peerCert;
   134 /** Called after the connection closes.
   135     You can check the connection's error property to see if it was normal or abnormal. */
   136 - (void) connectionDidClose: (TCPConnection*)connection;
   137 @end