AsyncSocket.h.svn-base
上传用户:kc0325
上传日期:2020-06-20
资源大小:204k
文件大小:11k
源码类别:

iPhone

开发平台:

Objective-C

  1. //
  2. //  AsyncSocket.h
  3. //  
  4. //  This class is in the public domain.
  5. //  Originally created by Dustin Voss on Wed Jan 29 2003.
  6. //  Updated and maintained by Deusty Designs and the Mac development community.
  7. //
  8. //  http://code.google.com/p/cocoaasyncsocket/
  9. //
  10. #import <Foundation/Foundation.h>
  11. @class AsyncSocket;
  12. @class AsyncReadPacket;
  13. @class AsyncWritePacket;
  14. extern NSString *const AsyncSocketException;
  15. extern NSString *const AsyncSocketErrorDomain;
  16. enum AsyncSocketError
  17. {
  18. AsyncSocketCFSocketError = kCFSocketError, // From CFSocketError enum.
  19. AsyncSocketNoError = 0, // Never used.
  20. AsyncSocketCanceledError, // onSocketWillConnect: returned NO.
  21. AsyncSocketReadMaxedOutError,               // Reached set maxLength without completing
  22. AsyncSocketReadTimeoutError,
  23. AsyncSocketWriteTimeoutError
  24. };
  25. typedef enum AsyncSocketError AsyncSocketError;
  26. @interface NSObject (AsyncSocketDelegate)
  27. /**
  28.  * In the event of an error, the socket is closed.
  29.  * You may call "unreadData" during this call-back to get the last bit of data off the socket.
  30.  * When connecting, this delegate method may be called
  31.  * before"onSocket:didAcceptNewSocket:" or "onSocket:didConnectToHost:".
  32. **/
  33. - (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
  34. /**
  35.  * Called when a socket disconnects with or without error.  If you want to release a socket after it disconnects,
  36.  * do so here. It is not safe to do that during "onSocket:willDisconnectWithError:".
  37. **/
  38. - (void)onSocketDidDisconnect:(AsyncSocket *)sock;
  39. /**
  40.  * Called when a socket accepts a connection.  Another socket is spawned to handle it. The new socket will have
  41.  * the same delegate and will call "onSocket:didConnectToHost:port:".
  42. **/
  43. - (void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket;
  44. /**
  45.  * Called when a new socket is spawned to handle a connection.  This method should return the run-loop of the
  46.  * thread on which the new socket and its delegate should operate. If omitted, [NSRunLoop currentRunLoop] is used.
  47. **/
  48. - (NSRunLoop *)onSocket:(AsyncSocket *)sock wantsRunLoopForNewSocket:(AsyncSocket *)newSocket;
  49. /**
  50.  * Called when a socket is about to connect. This method should return YES to continue, or NO to abort.
  51.  * If aborted, will result in AsyncSocketCanceledError.
  52.  * 
  53.  * If the connectToHost:onPort:error: method was called, the delegate will be able to access and configure the
  54.  * CFReadStream and CFWriteStream as desired prior to connection.
  55.  *
  56.  * If the connectToAddress:error: method was called, the delegate will be able to access and configure the
  57.  * CFSocket and CFSocketNativeHandle (BSD socket) as desired prior to connection. You will be able to access and
  58.  * configure the CFReadStream and CFWriteStream in the onSocket:didConnectToHost:port: method.
  59. **/
  60. - (BOOL)onSocketWillConnect:(AsyncSocket *)sock;
  61. /**
  62.  * Called when a socket connects and is ready for reading and writing.
  63.  * The host parameter will be an IP address, not a DNS name.
  64. **/
  65. - (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port;
  66. /**
  67.  * Called when a socket has completed reading the requested data into memory.
  68.  * Not called if there is an error.
  69. **/
  70. - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;
  71. /**
  72.  * Called when a socket has read in data, but has not yet completed the read.
  73.  * This would occur if using readToData: or readToLength: methods.
  74.  * It may be used to for things such as updating progress bars.
  75. **/
  76. - (void)onSocket:(AsyncSocket *)sock didReadPartialDataOfLength:(CFIndex)partialLength tag:(long)tag;
  77. /**
  78.  * Called when a socket has completed writing the requested data. Not called if there is an error.
  79. **/
  80. - (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
  81. @end
  82. @interface AsyncSocket : NSObject
  83. {
  84. CFSocketRef theSocket;             // IPv4 accept or connect socket
  85. CFSocketRef theSocket6;            // IPv6 accept or connect socket
  86. CFReadStreamRef theReadStream;
  87. CFWriteStreamRef theWriteStream;
  88. CFRunLoopSourceRef theSource;      // For theSocket
  89. CFRunLoopSourceRef theSource6;     // For theSocket6
  90. CFRunLoopRef theRunLoop;
  91. CFSocketContext theContext;
  92. NSMutableArray *theReadQueue;
  93. AsyncReadPacket *theCurrentRead;
  94. NSTimer *theReadTimer;
  95. NSMutableData *partialReadBuffer;
  96. NSMutableArray *theWriteQueue;
  97. AsyncWritePacket *theCurrentWrite;
  98. NSTimer *theWriteTimer;
  99. id theDelegate;
  100. Byte theFlags;
  101. long theUserData;
  102. }
  103. - (id)init;
  104. - (id)initWithDelegate:(id)delegate;
  105. - (id)initWithDelegate:(id)delegate userData:(long)userData;
  106. /* String representation is long but has no "n". */
  107. - (NSString *)description;
  108. /**
  109.  * Use "canSafelySetDelegate" to see if there is any pending business (reads and writes) with the current delegate
  110.  * before changing it.  It is, of course, safe to change the delegate before connecting or accepting connections.
  111. **/
  112. - (id)delegate;
  113. - (BOOL)canSafelySetDelegate;
  114. - (void)setDelegate:(id)delegate;
  115. /* User data can be a long, or an id or void * cast to a long. */
  116. - (long)userData;
  117. - (void)setUserData:(long)userData;
  118. /* Don't use these to read or write. And don't close them, either! */
  119. - (CFSocketRef)getCFSocket;
  120. - (CFReadStreamRef)getCFReadStream;
  121. - (CFWriteStreamRef)getCFWriteStream;
  122. /**
  123.  * Once one of these methods is called, the AsyncSocket instance is locked in, and the rest can't be called without
  124.  * disconnecting the socket first.  If the attempt times out or fails, these methods either return NO or
  125.  * call "onSocket:willDisconnectWithError:" and "onSockedDidDisconnect:".
  126. **/
  127. - (BOOL)acceptOnPort:(UInt16)port error:(NSError **)errPtr;
  128. - (BOOL)acceptOnAddress:(NSString *)hostaddr port:(UInt16)port error:(NSError **)errPtr;
  129. - (BOOL)connectToHost:(NSString *)hostname onPort:(UInt16)port error:(NSError **)errPtr;
  130. - (BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError **)errPtr;
  131. /**
  132.  * Disconnects immediately. Any pending reads or writes are dropped.
  133. **/
  134. - (void)disconnect;
  135. /**
  136.  * Disconnects after all pending writes have completed.
  137.  * After calling this, the read and write methods (including "readDataWithTimeout:tag:") will do nothing.
  138.  * The socket will disconnect even if there are still pending reads.
  139. **/
  140. - (void)disconnectAfterWriting;
  141. /* Returns YES if the socket and streams are open, connected, and ready for reading and writing. */
  142. - (BOOL)isConnected;
  143. /**
  144.  * Returns the local or remote host and port to which this socket is connected, or nil and 0 if not connected.
  145.  * The host will be an IP address.
  146. **/
  147. - (NSString *)connectedHost;
  148. - (UInt16)connectedPort;
  149. - (NSString *)localHost;
  150. - (UInt16)localPort;
  151. - (BOOL)isIPv4;
  152. - (BOOL)isIPv6;
  153. // The readData and writeData methods won't block. To not time out, use a negative time interval.
  154. // If they time out, "onSocket:disconnectWithError:" is called. The tag is for your convenience.
  155. // You can use it as an array index, step number, state id, pointer, etc., just like the socket's user data.
  156. /**
  157.  * This will read a certain number of bytes into memory, and call the delegate method when those bytes have been read.
  158.  * If there is an error, partially read data is lost.
  159.  * If the length is 0, this method does nothing and the delegate is not called.
  160. **/
  161. - (void)readDataToLength:(CFIndex)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;
  162. /**
  163.  * This reads bytes until (and including) the passed "data" parameter, which acts as a separator.
  164.  * The bytes and the separator are returned by the delegate method.
  165.  * 
  166.  * If you pass nil or zero-length data as the "data" parameter,
  167.  * the method will do nothing, and the delegate will not be called.
  168.  * 
  169.  * To read a line from the socket, use the line separator (e.g. CRLF for HTTP, see below) as the "data" parameter.
  170.  * Note that this method is not character-set aware, so if a separator can occur naturally as part of the encoding for
  171.  * a character, the read will prematurely end.
  172. **/
  173. - (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
  174. /**
  175.  * Same as readDataToData:withTimeout:tag, with the additional restriction that the amount of data read
  176.  * may not surpass the given maxLength (specified in bytes).
  177.  * 
  178.  * If you pass a maxLength parameter that is less than the length of the data parameter,
  179.  * the method will do nothing, and the delegate will not be called.
  180.  * 
  181.  * If the max length is surpassed, it is treated the same as a timeout - the socket is closed.
  182.  * 
  183.  * Pass -1 as maxLength if no length restriction is desired, or simply use the readDataToData:withTimeout:tag method.
  184. **/
  185. - (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout maxLength:(CFIndex)length tag:(long)tag;
  186. /**
  187.  * Reads the first available bytes that become available on the socket.
  188. **/
  189. - (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag;
  190. /* Writes data to the socket, and calls the delegate when finished.
  191.  * 
  192.  * If you pass in nil or zero-length data, this method does nothing and the delegate will not be called.
  193. **/
  194. - (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
  195. /**
  196.  * Returns progress of current read or write, from 0.0 to 1.0, or NaN if no read/write (use isnan() to check).
  197.  * "tag", "done" and "total" will be filled in if they aren't NULL.
  198. **/
  199. - (float)progressOfReadReturningTag:(long *)tag bytesDone:(CFIndex *)done total:(CFIndex *)total;
  200. - (float)progressOfWriteReturningTag:(long *)tag bytesDone:(CFIndex *)done total:(CFIndex *)total;
  201. /**
  202.  * For handling readDataToData requests, data is necessarily read from the socket in small increments.
  203.  * The performance can be improved by allowing AsyncSocket to read larger chunks at a time and
  204.  * store any overflow in a small internal buffer.
  205.  * This is termed pre-buffering, as some data may be read for you before you ask for it.
  206.  * If you use readDataToData a lot, enabling pre-buffering may offer a small performance improvement.
  207.  * 
  208.  * Pre-buffering is disabled by default. You must explicitly enable it to turn it on.
  209.  * 
  210.  * Note: If your protocol negotiates upgrades to TLS (as opposed to using TLS from the start), you should
  211.  * consider how, if at all, pre-buffering could affect the TLS negotiation sequence.
  212.  * This is because TLS runs atop TCP, and requires sending/receiving a TLS handshake over the TCP socket.
  213.  * If the negotiation sequence is poorly designed, pre-buffering could potentially pre-read part of the TLS handshake,
  214.  * thus causing TLS to fail. In almost all cases, especially when implementing a formalized protocol, this will never
  215.  * be a hazard.
  216. **/
  217. - (void)enablePreBuffering;
  218. /**
  219.  * In the event of an error, this method may be called during onSocket:willDisconnectWithError: to read
  220.  * any data that's left on the socket.
  221. **/
  222. - (NSData *)unreadData;
  223. /* A few common line separators, for use with "readDataToData:withTimeout:tag:". */
  224. + (NSData *)CRLFData;   // 0x0D0A
  225. + (NSData *)CRData;     // 0x0D
  226. + (NSData *)LFData;     // 0x0A
  227. + (NSData *)ZeroData;   // 0x00
  228. @end