Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
805 | - | 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 | |||
11 | #import <Foundation/Foundation.h> |
||
12 | |||
13 | @class AsyncSocket; |
||
14 | @class AsyncReadPacket; |
||
15 | @class AsyncWritePacket; |
||
16 | |||
17 | extern NSString *const AsyncSocketException; |
||
18 | extern NSString *const AsyncSocketErrorDomain; |
||
19 | |||
20 | enum AsyncSocketError |
||
21 | { |
||
22 | AsyncSocketCFSocketError = kCFSocketError, // From CFSocketError enum. |
||
23 | AsyncSocketNoError = 0, // Never used. |
||
24 | AsyncSocketCanceledError, // onSocketWillConnect: returned NO. |
||
25 | AsyncSocketConnectTimeoutError, |
||
26 | AsyncSocketReadMaxedOutError, // Reached set maxLength without completing |
||
27 | AsyncSocketReadTimeoutError, |
||
28 | AsyncSocketWriteTimeoutError |
||
29 | }; |
||
30 | typedef enum AsyncSocketError AsyncSocketError; |
||
31 | |||
32 | @interface NSObject (AsyncSocketDelegate) |
||
33 | |||
34 | /** |
||
35 | * In the event of an error, the socket is closed. |
||
36 | * You may call "unreadData" during this call-back to get the last bit of data off the socket. |
||
37 | * When connecting, this delegate method may be called |
||
38 | * before"onSocket:didAcceptNewSocket:" or "onSocket:didConnectToHost:". |
||
39 | **/ |
||
40 | - (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err; |
||
41 | |||
42 | /** |
||
43 | * Called when a socket disconnects with or without error. If you want to release a socket after it disconnects, |
||
44 | * do so here. It is not safe to do that during "onSocket:willDisconnectWithError:". |
||
45 | * |
||
46 | * If you call the disconnect method, and the socket wasn't already disconnected, |
||
47 | * this delegate method will be called before the disconnect method returns. |
||
48 | **/ |
||
49 | - (void)onSocketDidDisconnect:(AsyncSocket *)sock; |
||
50 | |||
51 | /** |
||
52 | * Called when a socket accepts a connection. Another socket is spawned to handle it. The new socket will have |
||
53 | * the same delegate and will call "onSocket:didConnectToHost:port:". |
||
54 | **/ |
||
55 | - (void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket; |
||
56 | |||
57 | /** |
||
58 | * Called when a new socket is spawned to handle a connection. This method should return the run-loop of the |
||
59 | * thread on which the new socket and its delegate should operate. If omitted, [NSRunLoop currentRunLoop] is used. |
||
60 | **/ |
||
61 | - (NSRunLoop *)onSocket:(AsyncSocket *)sock wantsRunLoopForNewSocket:(AsyncSocket *)newSocket; |
||
62 | |||
63 | /** |
||
64 | * Called when a socket is about to connect. This method should return YES to continue, or NO to abort. |
||
65 | * If aborted, will result in AsyncSocketCanceledError. |
||
66 | * |
||
67 | * If the connectToHost:onPort:error: method was called, the delegate will be able to access and configure the |
||
68 | * CFReadStream and CFWriteStream as desired prior to connection. |
||
69 | * |
||
70 | * If the connectToAddress:error: method was called, the delegate will be able to access and configure the |
||
71 | * CFSocket and CFSocketNativeHandle (BSD socket) as desired prior to connection. You will be able to access and |
||
72 | * configure the CFReadStream and CFWriteStream in the onSocket:didConnectToHost:port: method. |
||
73 | **/ |
||
74 | - (BOOL)onSocketWillConnect:(AsyncSocket *)sock; |
||
75 | |||
76 | /** |
||
77 | * Called when a socket connects and is ready for reading and writing. |
||
78 | * The host parameter will be an IP address, not a DNS name. |
||
79 | **/ |
||
80 | - (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port; |
||
81 | |||
82 | /** |
||
83 | * Called when a socket has completed reading the requested data into memory. |
||
84 | * Not called if there is an error. |
||
85 | **/ |
||
86 | - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag; |
||
87 | |||
88 | /** |
||
89 | * Called when a socket has read in data, but has not yet completed the read. |
||
90 | * This would occur if using readToData: or readToLength: methods. |
||
91 | * It may be used to for things such as updating progress bars. |
||
92 | **/ |
||
93 | - (void)onSocket:(AsyncSocket *)sock didReadPartialDataOfLength:(CFIndex)partialLength tag:(long)tag; |
||
94 | |||
95 | /** |
||
96 | * Called when a socket has completed writing the requested data. Not called if there is an error. |
||
97 | **/ |
||
98 | - (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag; |
||
99 | |||
100 | /** |
||
101 | * Called when a socket has written some data, but has not yet completed the entire write. |
||
102 | * It may be used to for things such as updating progress bars. |
||
103 | **/ |
||
104 | - (void)onSocket:(AsyncSocket *)sock didWritePartialDataOfLength:(CFIndex)partialLength tag:(long)tag; |
||
105 | |||
106 | /** |
||
107 | * Called if a read operation has reached its timeout without completing. |
||
108 | * This method allows you to optionally extend the timeout. |
||
109 | * If you return a positive time interval (> 0) the read's timeout will be extended by the given amount. |
||
110 | * If you don't implement this method, or return a non-positive time interval (<= 0) the read will timeout as usual. |
||
111 | * |
||
112 | * The elapsed parameter is the sum of the original timeout, plus any additions previously added via this method. |
||
113 | * The length parameter is the number of bytes that have been read so far for the read operation. |
||
114 | * |
||
115 | * Note that this method may be called multiple times for a single read if you return positive numbers. |
||
116 | **/ |
||
117 | - (NSTimeInterval)onSocket:(AsyncSocket *)sock |
||
118 | shouldTimeoutReadWithTag:(long)tag |
||
119 | elapsed:(NSTimeInterval)elapsed |
||
120 | bytesDone:(CFIndex)length; |
||
121 | |||
122 | /** |
||
123 | * Called if a write operation has reached its timeout without completing. |
||
124 | * This method allows you to optionally extend the timeout. |
||
125 | * If you return a positive time interval (> 0) the write's timeout will be extended by the given amount. |
||
126 | * If you don't implement this method, or return a non-positive time interval (<= 0) the write will timeout as usual. |
||
127 | * |
||
128 | * The elapsed parameter is the sum of the original timeout, plus any additions previously added via this method. |
||
129 | * The length parameter is the number of bytes that have been written so far for the write operation. |
||
130 | * |
||
131 | * Note that this method may be called multiple times for a single write if you return positive numbers. |
||
132 | **/ |
||
133 | - (NSTimeInterval)onSocket:(AsyncSocket *)sock |
||
134 | shouldTimeoutWriteWithTag:(long)tag |
||
135 | elapsed:(NSTimeInterval)elapsed |
||
136 | bytesDone:(CFIndex)length; |
||
137 | |||
138 | /** |
||
139 | * Called after the socket has successfully completed SSL/TLS negotiation. |
||
140 | * This method is not called unless you use the provided startTLS method. |
||
141 | * |
||
142 | * If a SSL/TLS negotiation fails (invalid certificate, etc) then the socket will immediately close, |
||
143 | * and the onSocket:willDisconnectWithError: delegate method will be called with the specific SSL error code. |
||
144 | **/ |
||
145 | - (void)onSocketDidSecure:(AsyncSocket *)sock; |
||
146 | |||
147 | @end |
||
148 | |||
149 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
150 | #pragma mark - |
||
151 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
||
152 | |||
153 | @interface AsyncSocket : NSObject |
||
154 | { |
||
155 | CFSocketRef theSocket4; // IPv4 accept or connect socket |
||
156 | CFSocketRef theSocket6; // IPv6 accept or connect socket |
||
157 | CFReadStreamRef theReadStream; |
||
158 | CFWriteStreamRef theWriteStream; |
||
159 | |||
160 | CFRunLoopSourceRef theSource4; // For theSocket4 |
||
161 | CFRunLoopSourceRef theSource6; // For theSocket6 |
||
162 | CFRunLoopRef theRunLoop; |
||
163 | CFSocketContext theContext; |
||
164 | NSArray *theRunLoopModes; |
||
165 | |||
166 | NSTimer *theConnectTimer; |
||
167 | |||
168 | NSMutableArray *theReadQueue; |
||
169 | AsyncReadPacket *theCurrentRead; |
||
170 | NSTimer *theReadTimer; |
||
171 | NSMutableData *partialReadBuffer; |
||
172 | |||
173 | NSMutableArray *theWriteQueue; |
||
174 | AsyncWritePacket *theCurrentWrite; |
||
175 | NSTimer *theWriteTimer; |
||
176 | |||
177 | id theDelegate; |
||
178 | UInt16 theFlags; |
||
179 | |||
180 | long theUserData; |
||
181 | } |
||
182 | |||
183 | - (id)init; |
||
184 | - (id)initWithDelegate:(id)delegate; |
||
185 | - (id)initWithDelegate:(id)delegate userData:(long)userData; |
||
186 | |||
187 | /* String representation is long but has no "\n". */ |
||
188 | - (NSString *)description; |
||
189 | |||
190 | /** |
||
191 | * Use "canSafelySetDelegate" to see if there is any pending business (reads and writes) with the current delegate |
||
192 | * before changing it. It is, of course, safe to change the delegate before connecting or accepting connections. |
||
193 | **/ |
||
194 | - (id)delegate; |
||
195 | - (BOOL)canSafelySetDelegate; |
||
196 | - (void)setDelegate:(id)delegate; |
||
197 | |||
198 | /* User data can be a long, or an id or void * cast to a long. */ |
||
199 | - (long)userData; |
||
200 | - (void)setUserData:(long)userData; |
||
201 | |||
202 | /* Don't use these to read or write. And don't close them either! */ |
||
203 | - (CFSocketRef)getCFSocket; |
||
204 | - (CFReadStreamRef)getCFReadStream; |
||
205 | - (CFWriteStreamRef)getCFWriteStream; |
||
206 | |||
207 | // Once one of the accept or connect methods are called, the AsyncSocket instance is locked in |
||
208 | // and the other accept/connect methods can't be called without disconnecting the socket first. |
||
209 | // If the attempt fails or times out, these methods either return NO or |
||
210 | // call "onSocket:willDisconnectWithError:" and "onSockedDidDisconnect:". |
||
211 | |||
212 | // When an incoming connection is accepted, AsyncSocket invokes several delegate methods. |
||
213 | // These methods are (in chronological order): |
||
214 | // 1. onSocket:didAcceptNewSocket: |
||
215 | // 2. onSocket:wantsRunLoopForNewSocket: |
||
216 | // 3. onSocketWillConnect: |
||
217 | // |
||
218 | // Your server code will need to retain the accepted socket (if you want to accept it). |
||
219 | // The best place to do this is probably in the onSocket:didAcceptNewSocket: method. |
||
220 | // |
||
221 | // After the read and write streams have been setup for the newly accepted socket, |
||
222 | // the onSocket:didConnectToHost:port: method will be called on the proper run loop. |
||
223 | // |
||
224 | // Multithreading Note: If you're going to be moving the newly accepted socket to another run |
||
225 | // loop by implementing onSocket:wantsRunLoopForNewSocket:, then you should wait until the |
||
226 | // onSocket:didConnectToHost:port: method before calling read, write, or startTLS methods. |
||
227 | // Otherwise read/write events are scheduled on the incorrect runloop, and chaos may ensue. |
||
228 | |||
229 | /** |
||
230 | * Tells the socket to begin listening and accepting connections on the given port. |
||
231 | * When a connection comes in, the AsyncSocket instance will call the various delegate methods (see above). |
||
232 | * The socket will listen on all available interfaces (e.g. wifi, ethernet, etc) |
||
233 | **/ |
||
234 | - (BOOL)acceptOnPort:(UInt16)port error:(NSError **)errPtr; |
||
235 | |||
236 | /** |
||
237 | * This method is the same as acceptOnPort:error: with the additional option |
||
238 | * of specifying which interface to listen on. So, for example, if you were writing code for a server that |
||
239 | * has multiple IP addresses, you could specify which address you wanted to listen on. Or you could use it |
||
240 | * to specify that the socket should only accept connections over ethernet, and not other interfaces such as wifi. |
||
241 | * You may also use the special strings "localhost" or "loopback" to specify that |
||
242 | * the socket only accept connections from the local machine. |
||
243 | * |
||
244 | * To accept connections on any interface pass nil, or simply use the acceptOnPort:error: method. |
||
245 | **/ |
||
246 | - (BOOL)acceptOnInterface:(NSString *)interface port:(UInt16)port error:(NSError **)errPtr; |
||
247 | |||
248 | /** |
||
249 | * Connects to the given host and port. |
||
250 | * The host may be a domain name (e.g. "deusty.com") or an IP address string (e.g. "192.168.0.2") |
||
251 | **/ |
||
252 | - (BOOL)connectToHost:(NSString *)hostname onPort:(UInt16)port error:(NSError **)errPtr; |
||
253 | |||
254 | /** |
||
255 | * This method is the same as connectToHost:onPort:error: with an additional timeout option. |
||
256 | * To not time out use a negative time interval, or simply use the connectToHost:onPort:error: method. |
||
257 | **/ |
||
258 | - (BOOL)connectToHost:(NSString *)hostname |
||
259 | onPort:(UInt16)port |
||
260 | withTimeout:(NSTimeInterval)timeout |
||
261 | error:(NSError **)errPtr; |
||
262 | |||
263 | /** |
||
264 | * Connects to the given address, specified as a sockaddr structure wrapped in a NSData object. |
||
265 | * For example, a NSData object returned from NSNetservice's addresses method. |
||
266 | * |
||
267 | * If you have an existing struct sockaddr you can convert it to a NSData object like so: |
||
268 | * struct sockaddr sa -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len]; |
||
269 | * struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len]; |
||
270 | **/ |
||
271 | - (BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError **)errPtr; |
||
272 | |||
273 | /** |
||
274 | * This method is the same as connectToAddress:error: with an additional timeout option. |
||
275 | * To not time out use a negative time interval, or simply use the connectToAddress:error: method. |
||
276 | **/ |
||
277 | - (BOOL)connectToAddress:(NSData *)remoteAddr withTimeout:(NSTimeInterval)timeout error:(NSError **)errPtr; |
||
278 | |||
279 | /** |
||
280 | * Disconnects immediately. Any pending reads or writes are dropped. |
||
281 | * If the socket is not already disconnected, the onSocketDidDisconnect delegate method |
||
282 | * will be called immediately, before this method returns. |
||
283 | * |
||
284 | * Please note the recommended way of releasing an AsyncSocket instance (e.g. in a dealloc method) |
||
285 | * [asyncSocket setDelegate:nil]; |
||
286 | * [asyncSocket disconnect]; |
||
287 | * [asyncSocket release]; |
||
288 | **/ |
||
289 | - (void)disconnect; |
||
290 | |||
291 | /** |
||
292 | * Disconnects after all pending reads have completed. |
||
293 | * After calling this, the read and write methods will do nothing. |
||
294 | * The socket will disconnect even if there are still pending writes. |
||
295 | **/ |
||
296 | - (void)disconnectAfterReading; |
||
297 | |||
298 | /** |
||
299 | * Disconnects after all pending writes have completed. |
||
300 | * After calling this, the read and write methods will do nothing. |
||
301 | * The socket will disconnect even if there are still pending reads. |
||
302 | **/ |
||
303 | - (void)disconnectAfterWriting; |
||
304 | |||
305 | /** |
||
306 | * Disconnects after all pending reads and writes have completed. |
||
307 | * After calling this, the read and write methods will do nothing. |
||
308 | **/ |
||
309 | - (void)disconnectAfterReadingAndWriting; |
||
310 | |||
311 | /* Returns YES if the socket and streams are open, connected, and ready for reading and writing. */ |
||
312 | - (BOOL)isConnected; |
||
313 | |||
314 | /** |
||
315 | * Returns the local or remote host and port to which this socket is connected, or nil and 0 if not connected. |
||
316 | * The host will be an IP address. |
||
317 | **/ |
||
318 | - (NSString *)connectedHost; |
||
319 | - (UInt16)connectedPort; |
||
320 | |||
321 | - (NSString *)localHost; |
||
322 | - (UInt16)localPort; |
||
323 | |||
324 | /** |
||
325 | * Returns the local or remote address to which this socket is connected, |
||
326 | * specified as a sockaddr structure wrapped in a NSData object. |
||
327 | * |
||
328 | * See also the connectedHost, connectedPort, localHost and localPort methods. |
||
329 | **/ |
||
330 | - (NSData *)connectedAddress; |
||
331 | - (NSData *)localAddress; |
||
332 | |||
333 | /** |
||
334 | * Returns whether the socket is IPv4 or IPv6. |
||
335 | * An accepting socket may be both. |
||
336 | **/ |
||
337 | - (BOOL)isIPv4; |
||
338 | - (BOOL)isIPv6; |
||
339 | |||
340 | // The readData and writeData methods won't block. |
||
341 | // |
||
342 | // You may optionally set a timeout for any read/write operation. (To not timeout, use a negative time interval.) |
||
343 | // If a read/write opertion times out, the corresponding "onSocket:shouldTimeout..." delegate method |
||
344 | // is called to optionally allow you to extend the timeout. |
||
345 | // Upon a timeout, the "onSocket:willDisconnectWithError:" method is called, followed by "onSocketDidDisconnect". |
||
346 | // |
||
347 | // The tag is for your convenience. |
||
348 | // You can use it as an array index, step number, state id, pointer, etc., just like the socket's user data. |
||
349 | |||
350 | /** |
||
351 | * This will read a certain number of bytes into memory, and call the delegate method when those bytes have been read. |
||
352 | * |
||
353 | * If the length is 0, this method does nothing and the delegate is not called. |
||
354 | * If the timeout value is negative, the read operation will not use a timeout. |
||
355 | **/ |
||
356 | - (void)readDataToLength:(CFIndex)length withTimeout:(NSTimeInterval)timeout tag:(long)tag; |
||
357 | |||
358 | /** |
||
359 | * This reads bytes until (and including) the passed "data" parameter, which acts as a separator. |
||
360 | * The bytes and the separator are returned by the delegate method. |
||
361 | * |
||
362 | * If you pass nil or zero-length data as the "data" parameter, |
||
363 | * the method will do nothing, and the delegate will not be called. |
||
364 | * If the timeout value is negative, the read operation will not use a timeout. |
||
365 | * |
||
366 | * To read a line from the socket, use the line separator (e.g. CRLF for HTTP, see below) as the "data" parameter. |
||
367 | * Note that this method is not character-set aware, so if a separator can occur naturally as part of the encoding for |
||
368 | * a character, the read will prematurely end. |
||
369 | **/ |
||
370 | - (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag; |
||
371 | |||
372 | /** |
||
373 | * Same as readDataToData:withTimeout:tag, with the additional restriction that the amount of data read |
||
374 | * may not surpass the given maxLength (specified in bytes). |
||
375 | * |
||
376 | * If you pass a maxLength parameter that is less than the length of the data parameter, |
||
377 | * the method will do nothing, and the delegate will not be called. |
||
378 | * |
||
379 | * If the max length is surpassed, it is treated the same as a timeout - the socket is closed. |
||
380 | * |
||
381 | * Pass -1 as maxLength if no length restriction is desired, or simply use the readDataToData:withTimeout:tag method. |
||
382 | **/ |
||
383 | - (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout maxLength:(CFIndex)length tag:(long)tag; |
||
384 | |||
385 | /** |
||
386 | * Reads the first available bytes that become available on the socket. |
||
387 | * |
||
388 | * If the timeout value is negative, the read operation will not use a timeout. |
||
389 | **/ |
||
390 | - (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag; |
||
391 | |||
392 | /** |
||
393 | * Writes data to the socket, and calls the delegate when finished. |
||
394 | * |
||
395 | * If you pass in nil or zero-length data, this method does nothing and the delegate will not be called. |
||
396 | * If the timeout value is negative, the write operation will not use a timeout. |
||
397 | **/ |
||
398 | - (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag; |
||
399 | |||
400 | /** |
||
401 | * Returns progress of current read or write, from 0.0 to 1.0, or NaN if no read/write (use isnan() to check). |
||
402 | * "tag", "done" and "total" will be filled in if they aren't NULL. |
||
403 | **/ |
||
404 | - (float)progressOfReadReturningTag:(long *)tag bytesDone:(CFIndex *)done total:(CFIndex *)total; |
||
405 | - (float)progressOfWriteReturningTag:(long *)tag bytesDone:(CFIndex *)done total:(CFIndex *)total; |
||
406 | |||
407 | /** |
||
408 | * Secures the connection using SSL/TLS. |
||
409 | * |
||
410 | * This method may be called at any time, and the TLS handshake will occur after all pending reads and writes |
||
411 | * are finished. This allows one the option of sending a protocol dependent StartTLS message, and queuing |
||
412 | * the upgrade to TLS at the same time, without having to wait for the write to finish. |
||
413 | * Any reads or writes scheduled after this method is called will occur over the secured connection. |
||
414 | * |
||
415 | * The possible keys and values for the TLS settings are well documented. |
||
416 | * Some possible keys are: |
||
417 | * - kCFStreamSSLLevel |
||
418 | * - kCFStreamSSLAllowsExpiredCertificates |
||
419 | * - kCFStreamSSLAllowsExpiredRoots |
||
420 | * - kCFStreamSSLAllowsAnyRoot |
||
421 | * - kCFStreamSSLValidatesCertificateChain |
||
422 | * - kCFStreamSSLPeerName |
||
423 | * - kCFStreamSSLCertificates |
||
424 | * - kCFStreamSSLIsServer |
||
425 | * |
||
426 | * Please refer to Apple's documentation for associated values, as well as other possible keys. |
||
427 | * |
||
428 | * If you pass in nil or an empty dictionary, the default settings will be used. |
||
429 | * |
||
430 | * The default settings will check to make sure the remote party's certificate is signed by a |
||
431 | * trusted 3rd party certificate agency (e.g. verisign) and that the certificate is not expired. |
||
432 | * However it will not verify the name on the certificate unless you |
||
433 | * give it a name to verify against via the kCFStreamSSLPeerName key. |
||
434 | * The security implications of this are important to understand. |
||
435 | * Imagine you are attempting to create a secure connection to MySecureServer.com, |
||
436 | * but your socket gets directed to MaliciousServer.com because of a hacked DNS server. |
||
437 | * If you simply use the default settings, and MaliciousServer.com has a valid certificate, |
||
438 | * the default settings will not detect any problems since the certificate is valid. |
||
439 | * To properly secure your connection in this particular scenario you |
||
440 | * should set the kCFStreamSSLPeerName property to "MySecureServer.com". |
||
441 | * If you do not know the peer name of the remote host in advance (for example, you're not sure |
||
442 | * if it will be "domain.com" or "www.domain.com"), then you can use the default settings to validate the |
||
443 | * certificate, and then use the X509Certificate class to verify the issuer after the socket has been secured. |
||
444 | * The X509Certificate class is part of the CocoaAsyncSocket open source project. |
||
445 | **/ |
||
446 | - (void)startTLS:(NSDictionary *)tlsSettings; |
||
447 | |||
448 | /** |
||
449 | * For handling readDataToData requests, data is necessarily read from the socket in small increments. |
||
450 | * The performance can be much improved by allowing AsyncSocket to read larger chunks at a time and |
||
451 | * store any overflow in a small internal buffer. |
||
452 | * This is termed pre-buffering, as some data may be read for you before you ask for it. |
||
453 | * If you use readDataToData a lot, enabling pre-buffering will result in better performance, especially on the iPhone. |
||
454 | * |
||
455 | * The default pre-buffering state is controlled by the DEFAULT_PREBUFFERING definition. |
||
456 | * It is highly recommended one leave this set to YES. |
||
457 | * |
||
458 | * This method exists in case pre-buffering needs to be disabled by default for some unforeseen reason. |
||
459 | * In that case, this method exists to allow one to easily enable pre-buffering when ready. |
||
460 | **/ |
||
461 | - (void)enablePreBuffering; |
||
462 | |||
463 | /** |
||
464 | * When you create an AsyncSocket, it is added to the runloop of the current thread. |
||
465 | * So for manually created sockets, it is easiest to simply create the socket on the thread you intend to use it. |
||
466 | * |
||
467 | * If a new socket is accepted, the delegate method onSocket:wantsRunLoopForNewSocket: is called to |
||
468 | * allow you to place the socket on a separate thread. This works best in conjunction with a thread pool design. |
||
469 | * |
||
470 | * If, however, you need to move the socket to a separate thread at a later time, this |
||
471 | * method may be used to accomplish the task. |
||
472 | * |
||
473 | * This method must be called from the thread/runloop the socket is currently running on. |
||
474 | * |
||
475 | * Note: After calling this method, all further method calls to this object should be done from the given runloop. |
||
476 | * Also, all delegate calls will be sent on the given runloop. |
||
477 | **/ |
||
478 | - (BOOL)moveToRunLoop:(NSRunLoop *)runLoop; |
||
479 | |||
480 | /** |
||
481 | * Allows you to configure which run loop modes the socket uses. |
||
482 | * The default set of run loop modes is NSDefaultRunLoopMode. |
||
483 | * |
||
484 | * If you'd like your socket to continue operation during other modes, you may want to add modes such as |
||
485 | * NSModalPanelRunLoopMode or NSEventTrackingRunLoopMode. Or you may simply want to use NSRunLoopCommonModes. |
||
486 | * |
||
487 | * Accepted sockets will automatically inherit the same run loop modes as the listening socket. |
||
488 | * |
||
489 | * Note: NSRunLoopCommonModes is defined in 10.5. For previous versions one can use kCFRunLoopCommonModes. |
||
490 | **/ |
||
491 | - (BOOL)setRunLoopModes:(NSArray *)runLoopModes; |
||
492 | |||
493 | /** |
||
494 | * Returns the current run loop modes the AsyncSocket instance is operating in. |
||
495 | * The default set of run loop modes is NSDefaultRunLoopMode. |
||
496 | **/ |
||
497 | - (NSArray *)runLoopModes; |
||
498 | |||
499 | /** |
||
500 | * In the event of an error, this method may be called during onSocket:willDisconnectWithError: to read |
||
501 | * any data that's left on the socket. |
||
502 | **/ |
||
503 | - (NSData *)unreadData; |
||
504 | |||
505 | /* A few common line separators, for use with the readDataToData:... methods. */ |
||
506 | + (NSData *)CRLFData; // 0x0D0A |
||
507 | + (NSData *)CRData; // 0x0D |
||
508 | + (NSData *)LFData; // 0x0A |
||
509 | + (NSData *)ZeroData; // 0x00 |
||
510 | |||
511 | @end |