PageRenderTime 40ms CodeModel.GetById 16ms app.highlight 16ms RepoModel.GetById 1ms app.codeStats 0ms

/GCD/GCDAsyncUdpSocket.h

https://github.com/coderlirui/CocoaAsyncSocket
C++ Header | 996 lines | 137 code | 80 blank | 779 comment | 0 complexity | 8318f4d9a793af3d9c3e8de1980fca22 MD5 | raw file
  1//  
  2//  GCDAsyncUdpSocket
  3//  
  4//  This class is in the public domain.
  5//  Originally created by Robbie Hanson of Deusty LLC.
  6//  Updated and maintained by Deusty LLC and the Apple development community.
  7//  
  8//  https://github.com/robbiehanson/CocoaAsyncSocket
  9//
 10
 11#import <Foundation/Foundation.h>
 12#import <dispatch/dispatch.h>
 13#import <TargetConditionals.h>
 14#import <Availability.h>
 15
 16extern NSString *const GCDAsyncUdpSocketException;
 17extern NSString *const GCDAsyncUdpSocketErrorDomain;
 18
 19extern NSString *const GCDAsyncUdpSocketQueueName;
 20extern NSString *const GCDAsyncUdpSocketThreadName;
 21
 22enum GCDAsyncUdpSocketError
 23{
 24	GCDAsyncUdpSocketNoError = 0,          // Never used
 25	GCDAsyncUdpSocketBadConfigError,       // Invalid configuration
 26	GCDAsyncUdpSocketBadParamError,        // Invalid parameter was passed
 27	GCDAsyncUdpSocketSendTimeoutError,     // A send operation timed out
 28	GCDAsyncUdpSocketClosedError,          // The socket was closed
 29	GCDAsyncUdpSocketOtherError,           // Description provided in userInfo
 30};
 31typedef enum GCDAsyncUdpSocketError GCDAsyncUdpSocketError;
 32
 33/**
 34 * You may optionally set a receive filter for the socket.
 35 * A filter can provide several useful features:
 36 *    
 37 * 1. Many times udp packets need to be parsed.
 38 *    Since the filter can run in its own independent queue, you can parallelize this parsing quite easily.
 39 *    The end result is a parallel socket io, datagram parsing, and packet processing.
 40 * 
 41 * 2. Many times udp packets are discarded because they are duplicate/unneeded/unsolicited.
 42 *    The filter can prevent such packets from arriving at the delegate.
 43 *    And because the filter can run in its own independent queue, this doesn't slow down the delegate.
 44 * 
 45 *    - Since the udp protocol does not guarantee delivery, udp packets may be lost.
 46 *      Many protocols built atop udp thus provide various resend/re-request algorithms.
 47 *      This sometimes results in duplicate packets arriving.
 48 *      A filter may allow you to architect the duplicate detection code to run in parallel to normal processing.
 49 *    
 50 *    - Since the udp socket may be connectionless, its possible for unsolicited packets to arrive.
 51 *      Such packets need to be ignored.
 52 * 
 53 * 3. Sometimes traffic shapers are needed to simulate real world environments.
 54 *    A filter allows you to write custom code to simulate such environments.
 55 *    The ability to code this yourself is especially helpful when your simulated environment
 56 *    is more complicated than simple traffic shaping (e.g. simulating a cone port restricted router),
 57 *    or the system tools to handle this aren't available (e.g. on a mobile device).
 58 * 
 59 * @param data    - The packet that was received.
 60 * @param address - The address the data was received from.
 61 *                  See utilities section for methods to extract info from address.
 62 * @param context - Out parameter you may optionally set, which will then be passed to the delegate method.
 63 *                  For example, filter block can parse the data and then,
 64 *                  pass the parsed data to the delegate.
 65 * 
 66 * @returns - YES if the received packet should be passed onto the delegate.
 67 *            NO if the received packet should be discarded, and not reported to the delegete.
 68 * 
 69 * Example:
 70 * 
 71 * GCDAsyncUdpSocketReceiveFilterBlock filter = ^BOOL (NSData *data, NSData *address, id *context) {
 72 * 
 73 *     MyProtocolMessage *msg = [MyProtocol parseMessage:data];
 74 *     
 75 *     *context = response;
 76 *     return (response != nil);
 77 * };
 78 * [udpSocket setReceiveFilter:filter withQueue:myParsingQueue];
 79 * 
 80**/
 81typedef BOOL (^GCDAsyncUdpSocketReceiveFilterBlock)(NSData *data, NSData *address, id *context);
 82
 83/**
 84 * You may optionally set a send filter for the socket.
 85 * A filter can provide several interesting possibilities:
 86 * 
 87 * 1. Optional caching of resolved addresses for domain names.
 88 *    The cache could later be consulted, resulting in fewer system calls to getaddrinfo.
 89 * 
 90 * 2. Reusable modules of code for bandwidth monitoring.
 91 * 
 92 * 3. Sometimes traffic shapers are needed to simulate real world environments.
 93 *    A filter allows you to write custom code to simulate such environments.
 94 *    The ability to code this yourself is especially helpful when your simulated environment
 95 *    is more complicated than simple traffic shaping (e.g. simulating a cone port restricted router),
 96 *    or the system tools to handle this aren't available (e.g. on a mobile device).
 97 * 
 98 * @param data    - The packet that was received.
 99 * @param address - The address the data was received from.
100 *                  See utilities section for methods to extract info from address.
101 * @param tag     - The tag that was passed in the send method.
102 * 
103 * @returns - YES if the packet should actually be sent over the socket.
104 *            NO if the packet should be silently dropped (not sent over the socket).
105 * 
106 * Regardless of the return value, the delegate will be informed that the packet was successfully sent.
107 *
108**/
109typedef BOOL (^GCDAsyncUdpSocketSendFilterBlock)(NSData *data, NSData *address, long tag);
110
111
112@interface GCDAsyncUdpSocket : NSObject
113
114/**
115 * GCDAsyncUdpSocket uses the standard delegate paradigm,
116 * but executes all delegate callbacks on a given delegate dispatch queue.
117 * This allows for maximum concurrency, while at the same time providing easy thread safety.
118 * 
119 * You MUST set a delegate AND delegate dispatch queue before attempting to
120 * use the socket, or you will get an error.
121 * 
122 * The socket queue is optional.
123 * If you pass NULL, GCDAsyncSocket will automatically create its own socket queue.
124 * If you choose to provide a socket queue, the socket queue must not be a concurrent queue,
125 * then please see the discussion for the method markSocketQueueTargetQueue.
126 *
127 * The delegate queue and socket queue can optionally be the same.
128**/
129- (id)init;
130- (id)initWithSocketQueue:(dispatch_queue_t)sq;
131- (id)initWithDelegate:(id)aDelegate delegateQueue:(dispatch_queue_t)dq;
132- (id)initWithDelegate:(id)aDelegate delegateQueue:(dispatch_queue_t)dq socketQueue:(dispatch_queue_t)sq;
133
134#pragma mark Configuration
135
136- (id)delegate;
137- (void)setDelegate:(id)delegate;
138- (void)synchronouslySetDelegate:(id)delegate;
139
140- (dispatch_queue_t)delegateQueue;
141- (void)setDelegateQueue:(dispatch_queue_t)delegateQueue;
142- (void)synchronouslySetDelegateQueue:(dispatch_queue_t)delegateQueue;
143
144- (void)getDelegate:(id *)delegatePtr delegateQueue:(dispatch_queue_t *)delegateQueuePtr;
145- (void)setDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
146- (void)synchronouslySetDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
147
148/**
149 * By default, both IPv4 and IPv6 are enabled.
150 * 
151 * This means GCDAsyncUdpSocket automatically supports both protocols,
152 * and can send to IPv4 or IPv6 addresses,
153 * as well as receive over IPv4 and IPv6.
154 * 
155 * For operations that require DNS resolution, GCDAsyncUdpSocket supports both IPv4 and IPv6.
156 * If a DNS lookup returns only IPv4 results, GCDAsyncUdpSocket will automatically use IPv4.
157 * If a DNS lookup returns only IPv6 results, GCDAsyncUdpSocket will automatically use IPv6.
158 * If a DNS lookup returns both IPv4 and IPv6 results, then the protocol used depends on the configured preference.
159 * If IPv4 is preferred, then IPv4 is used.
160 * If IPv6 is preferred, then IPv6 is used.
161 * If neutral, then the first IP version in the resolved array will be used.
162 * 
163 * Starting with Mac OS X 10.7 Lion and iOS 5, the default IP preference is neutral.
164 * On prior systems the default IP preference is IPv4.
165 **/
166- (BOOL)isIPv4Enabled;
167- (void)setIPv4Enabled:(BOOL)flag;
168
169- (BOOL)isIPv6Enabled;
170- (void)setIPv6Enabled:(BOOL)flag;
171
172- (BOOL)isIPv4Preferred;
173- (BOOL)isIPv6Preferred;
174- (BOOL)isIPVersionNeutral;
175
176- (void)setPreferIPv4;
177- (void)setPreferIPv6;
178- (void)setIPVersionNeutral;
179
180/**
181 * Gets/Sets the maximum size of the buffer that will be allocated for receive operations.
182 * The default maximum size is 9216 bytes.
183 * 
184 * The theoretical maximum size of any IPv4 UDP packet is UINT16_MAX = 65535.
185 * The theoretical maximum size of any IPv6 UDP packet is UINT32_MAX = 4294967295.
186 * 
187 * Since the OS/GCD notifies us of the size of each received UDP packet,
188 * the actual allocated buffer size for each packet is exact.
189 * And in practice the size of UDP packets is generally much smaller than the max.
190 * Indeed most protocols will send and receive packets of only a few bytes,
191 * or will set a limit on the size of packets to prevent fragmentation in the IP layer.
192 * 
193 * If you set the buffer size too small, the sockets API in the OS will silently discard
194 * any extra data, and you will not be notified of the error.
195**/
196- (uint16_t)maxReceiveIPv4BufferSize;
197- (void)setMaxReceiveIPv4BufferSize:(uint16_t)max;
198
199- (uint32_t)maxReceiveIPv6BufferSize;
200- (void)setMaxReceiveIPv6BufferSize:(uint32_t)max;
201
202/**
203 * User data allows you to associate arbitrary information with the socket.
204 * This data is not used internally in any way.
205**/
206- (id)userData;
207- (void)setUserData:(id)arbitraryUserData;
208
209#pragma mark Diagnostics
210
211/**
212 * Returns the local address info for the socket.
213 * 
214 * The localAddress method returns a sockaddr structure wrapped in a NSData object.
215 * The localHost method returns the human readable IP address as a string.
216 * 
217 * Note: Address info may not be available until after the socket has been binded, connected
218 * or until after data has been sent.
219**/
220- (NSData *)localAddress;
221- (NSString *)localHost;
222- (uint16_t)localPort;
223
224- (NSData *)localAddress_IPv4;
225- (NSString *)localHost_IPv4;
226- (uint16_t)localPort_IPv4;
227
228- (NSData *)localAddress_IPv6;
229- (NSString *)localHost_IPv6;
230- (uint16_t)localPort_IPv6;
231
232/**
233 * Returns the remote address info for the socket.
234 * 
235 * The connectedAddress method returns a sockaddr structure wrapped in a NSData object.
236 * The connectedHost method returns the human readable IP address as a string.
237 * 
238 * Note: Since UDP is connectionless by design, connected address info
239 * will not be available unless the socket is explicitly connected to a remote host/port.
240 * If the socket is not connected, these methods will return nil / 0.
241**/
242- (NSData *)connectedAddress;
243- (NSString *)connectedHost;
244- (uint16_t)connectedPort;
245
246/**
247 * Returns whether or not this socket has been connected to a single host.
248 * By design, UDP is a connectionless protocol, and connecting is not needed.
249 * If connected, the socket will only be able to send/receive data to/from the connected host.
250**/
251- (BOOL)isConnected;
252
253/**
254 * Returns whether or not this socket has been closed.
255 * The only way a socket can be closed is if you explicitly call one of the close methods.
256**/
257- (BOOL)isClosed;
258
259/**
260 * Returns whether or not this socket is IPv4.
261 * 
262 * By default this will be true, unless:
263 * - IPv4 is disabled (via setIPv4Enabled:)
264 * - The socket is explicitly bound to an IPv6 address
265 * - The socket is connected to an IPv6 address
266**/
267- (BOOL)isIPv4;
268
269/**
270 * Returns whether or not this socket is IPv6.
271 * 
272 * By default this will be true, unless:
273 * - IPv6 is disabled (via setIPv6Enabled:)
274 * - The socket is explicitly bound to an IPv4 address
275 * _ The socket is connected to an IPv4 address
276 * 
277 * This method will also return false on platforms that do not support IPv6.
278 * Note: The iPhone does not currently support IPv6.
279**/
280- (BOOL)isIPv6;
281
282#pragma mark Binding
283
284/**
285 * Binds the UDP socket to the given port.
286 * Binding should be done for server sockets that receive data prior to sending it.
287 * Client sockets can skip binding,
288 * as the OS will automatically assign the socket an available port when it starts sending data.
289 * 
290 * You may optionally pass a port number of zero to immediately bind the socket,
291 * yet still allow the OS to automatically assign an available port.
292 * 
293 * You cannot bind a socket after its been connected.
294 * You can only bind a socket once.
295 * You can still connect a socket (if desired) after binding.
296 * 
297 * On success, returns YES.
298 * Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass NULL for errPtr.
299**/
300- (BOOL)bindToPort:(uint16_t)port error:(NSError **)errPtr;
301
302/**
303 * Binds the UDP socket to the given port and optional interface.
304 * Binding should be done for server sockets that receive data prior to sending it.
305 * Client sockets can skip binding,
306 * as the OS will automatically assign the socket an available port when it starts sending data.
307 * 
308 * You may optionally pass a port number of zero to immediately bind the socket,
309 * yet still allow the OS to automatically assign an available port.
310 * 
311 * The interface may be a name (e.g. "en1" or "lo0") or the corresponding IP address (e.g. "192.168.4.35").
312 * You may also use the special strings "localhost" or "loopback" to specify that
313 * the socket only accept packets from the local machine.
314 * 
315 * You cannot bind a socket after its been connected.
316 * You can only bind a socket once.
317 * You can still connect a socket (if desired) after binding.
318 * 
319 * On success, returns YES.
320 * Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass NULL for errPtr.
321**/
322- (BOOL)bindToPort:(uint16_t)port interface:(NSString *)interface error:(NSError **)errPtr;
323
324/**
325 * Binds the UDP socket to the given address, specified as a sockaddr structure wrapped in a NSData object.
326 * 
327 * If you have an existing struct sockaddr you can convert it to a NSData object like so:
328 * struct sockaddr sa  -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len];
329 * struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len];
330 * 
331 * Binding should be done for server sockets that receive data prior to sending it.
332 * Client sockets can skip binding,
333 * as the OS will automatically assign the socket an available port when it starts sending data.
334 * 
335 * You cannot bind a socket after its been connected.
336 * You can only bind a socket once.
337 * You can still connect a socket (if desired) after binding.
338 * 
339 * On success, returns YES.
340 * Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass NULL for errPtr.
341**/
342- (BOOL)bindToAddress:(NSData *)localAddr error:(NSError **)errPtr;
343
344#pragma mark Connecting
345
346/**
347 * Connects the UDP socket to the given host and port.
348 * By design, UDP is a connectionless protocol, and connecting is not needed.
349 * 
350 * Choosing to connect to a specific host/port has the following effect:
351 * - You will only be able to send data to the connected host/port.
352 * - You will only be able to receive data from the connected host/port.
353 * - You will receive ICMP messages that come from the connected host/port, such as "connection refused".
354 * 
355 * The actual process of connecting a UDP socket does not result in any communication on the socket.
356 * It simply changes the internal state of the socket.
357 * 
358 * You cannot bind a socket after it has been connected.
359 * You can only connect a socket once.
360 * 
361 * The host may be a domain name (e.g. "deusty.com") or an IP address string (e.g. "192.168.0.2").
362 * 
363 * This method is asynchronous as it requires a DNS lookup to resolve the given host name.
364 * If an obvious error is detected, this method immediately returns NO and sets errPtr.
365 * If you don't care about the error, you can pass nil for errPtr.
366 * Otherwise, this method returns YES and begins the asynchronous connection process.
367 * The result of the asynchronous connection process will be reported via the delegate methods.
368 **/
369- (BOOL)connectToHost:(NSString *)host onPort:(uint16_t)port error:(NSError **)errPtr;
370
371/**
372 * Connects the UDP socket to the given address, specified as a sockaddr structure wrapped in a NSData object.
373 * 
374 * If you have an existing struct sockaddr you can convert it to a NSData object like so:
375 * struct sockaddr sa  -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len];
376 * struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len];
377 * 
378 * By design, UDP is a connectionless protocol, and connecting is not needed.
379 * 
380 * Choosing to connect to a specific address has the following effect:
381 * - You will only be able to send data to the connected address.
382 * - You will only be able to receive data from the connected address.
383 * - You will receive ICMP messages that come from the connected address, such as "connection refused".
384 * 
385 * Connecting a UDP socket does not result in any communication on the socket.
386 * It simply changes the internal state of the socket.
387 * 
388 * You cannot bind a socket after its been connected.
389 * You can only connect a socket once.
390 * 
391 * On success, returns YES.
392 * Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass nil for errPtr.
393 * 
394 * Note: Unlike the connectToHost:onPort:error: method, this method does not require a DNS lookup.
395 * Thus when this method returns, the connection has either failed or fully completed.
396 * In other words, this method is synchronous, unlike the asynchronous connectToHost::: method.
397 * However, for compatibility and simplification of delegate code, if this method returns YES
398 * then the corresponding delegate method (udpSocket:didConnectToHost:port:) is still invoked.
399**/
400- (BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError **)errPtr;
401
402#pragma mark Multicast
403
404/**
405 * Join multicast group.
406 * Group should be an IP address (eg @"225.228.0.1").
407 * 
408 * On success, returns YES.
409 * Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass nil for errPtr.
410**/
411- (BOOL)joinMulticastGroup:(NSString *)group error:(NSError **)errPtr;
412
413/**
414 * Join multicast group.
415 * Group should be an IP address (eg @"225.228.0.1").
416 * The interface may be a name (e.g. "en1" or "lo0") or the corresponding IP address (e.g. "192.168.4.35").
417 * 
418 * On success, returns YES.
419 * Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass nil for errPtr.
420**/
421- (BOOL)joinMulticastGroup:(NSString *)group onInterface:(NSString *)interface error:(NSError **)errPtr;
422
423- (BOOL)leaveMulticastGroup:(NSString *)group error:(NSError **)errPtr;
424- (BOOL)leaveMulticastGroup:(NSString *)group onInterface:(NSString *)interface error:(NSError **)errPtr;
425
426#pragma mark Broadcast
427
428/**
429 * By default, the underlying socket in the OS will not allow you to send broadcast messages.
430 * In order to send broadcast messages, you need to enable this functionality in the socket.
431 * 
432 * A broadcast is a UDP message to addresses like "192.168.255.255" or "255.255.255.255" that is
433 * delivered to every host on the network.
434 * The reason this is generally disabled by default (by the OS) is to prevent
435 * accidental broadcast messages from flooding the network.
436**/
437- (BOOL)enableBroadcast:(BOOL)flag error:(NSError **)errPtr;
438
439#pragma mark Sending
440
441/**
442 * Asynchronously sends the given data, with the given timeout and tag.
443 * 
444 * This method may only be used with a connected socket.
445 * Recall that connecting is optional for a UDP socket.
446 * For connected sockets, data can only be sent to the connected address.
447 * For non-connected sockets, the remote destination is specified for each packet.
448 * For more information about optionally connecting udp sockets, see the documentation for the connect methods above.
449 * 
450 * @param data
451 *     The data to send.
452 *     If data is nil or zero-length, this method does nothing.
453 *     If passing NSMutableData, please read the thread-safety notice below.
454 * 
455 * @param timeout
456 *    The timeout for the send opeartion.
457 *    If the timeout value is negative, the send operation will not use a timeout.
458 * 
459 * @param tag
460 *    The tag is for your convenience.
461 *    It is not sent or received over the socket in any manner what-so-ever.
462 *    It is reported back as a parameter in the udpSocket:didSendDataWithTag:
463 *    or udpSocket:didNotSendDataWithTag:dueToError: methods.
464 *    You can use it as an array index, state id, type constant, etc.
465 * 
466 * 
467 * Thread-Safety Note:
468 * If the given data parameter is mutable (NSMutableData) then you MUST NOT alter the data while
469 * the socket is sending it. In other words, it's not safe to alter the data until after the delegate method
470 * udpSocket:didSendDataWithTag: or udpSocket:didNotSendDataWithTag:dueToError: is invoked signifying
471 * that this particular send operation has completed.
472 * This is due to the fact that GCDAsyncUdpSocket does NOT copy the data.
473 * It simply retains it for performance reasons.
474 * Often times, if NSMutableData is passed, it is because a request/response was built up in memory.
475 * Copying this data adds an unwanted/unneeded overhead.
476 * If you need to write data from an immutable buffer, and you need to alter the buffer before the socket
477 * completes sending the bytes (which is NOT immediately after this method returns, but rather at a later time
478 * when the delegate method notifies you), then you should first copy the bytes, and pass the copy to this method.
479**/
480- (void)sendData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
481
482/**
483 * Asynchronously sends the given data, with the given timeout and tag, to the given host and port.
484 * 
485 * This method cannot be used with a connected socket.
486 * Recall that connecting is optional for a UDP socket.
487 * For connected sockets, data can only be sent to the connected address.
488 * For non-connected sockets, the remote destination is specified for each packet.
489 * For more information about optionally connecting udp sockets, see the documentation for the connect methods above.
490 * 
491 * @param data
492 *     The data to send.
493 *     If data is nil or zero-length, this method does nothing.
494 *     If passing NSMutableData, please read the thread-safety notice below.
495 * 
496 * @param host
497 *     The destination to send the udp packet to.
498 *     May be specified as a domain name (e.g. "deusty.com") or an IP address string (e.g. "192.168.0.2").
499 *     You may also use the convenience strings of "loopback" or "localhost".
500 * 
501 * @param port
502 *    The port of the host to send to.
503 * 
504 * @param timeout
505 *    The timeout for the send opeartion.
506 *    If the timeout value is negative, the send operation will not use a timeout.
507 * 
508 * @param tag
509 *    The tag is for your convenience.
510 *    It is not sent or received over the socket in any manner what-so-ever.
511 *    It is reported back as a parameter in the udpSocket:didSendDataWithTag:
512 *    or udpSocket:didNotSendDataWithTag:dueToError: methods.
513 *    You can use it as an array index, state id, type constant, etc.
514 * 
515 * 
516 * Thread-Safety Note:
517 * If the given data parameter is mutable (NSMutableData) then you MUST NOT alter the data while
518 * the socket is sending it. In other words, it's not safe to alter the data until after the delegate method
519 * udpSocket:didSendDataWithTag: or udpSocket:didNotSendDataWithTag:dueToError: is invoked signifying
520 * that this particular send operation has completed.
521 * This is due to the fact that GCDAsyncUdpSocket does NOT copy the data.
522 * It simply retains it for performance reasons.
523 * Often times, if NSMutableData is passed, it is because a request/response was built up in memory.
524 * Copying this data adds an unwanted/unneeded overhead.
525 * If you need to write data from an immutable buffer, and you need to alter the buffer before the socket
526 * completes sending the bytes (which is NOT immediately after this method returns, but rather at a later time
527 * when the delegate method notifies you), then you should first copy the bytes, and pass the copy to this method.
528**/
529- (void)sendData:(NSData *)data
530          toHost:(NSString *)host
531            port:(uint16_t)port
532     withTimeout:(NSTimeInterval)timeout
533             tag:(long)tag;
534
535/**
536 * Asynchronously sends the given data, with the given timeout and tag, to the given address.
537 * 
538 * This method cannot be used with a connected socket.
539 * Recall that connecting is optional for a UDP socket.
540 * For connected sockets, data can only be sent to the connected address.
541 * For non-connected sockets, the remote destination is specified for each packet.
542 * For more information about optionally connecting udp sockets, see the documentation for the connect methods above.
543 * 
544 * @param data
545 *     The data to send.
546 *     If data is nil or zero-length, this method does nothing.
547 *     If passing NSMutableData, please read the thread-safety notice below.
548 * 
549 * @param remoteAddr
550 *     The address to send the data to (specified as a sockaddr structure wrapped in a NSData object).
551 * 
552 * @param timeout
553 *    The timeout for the send opeartion.
554 *    If the timeout value is negative, the send operation will not use a timeout.
555 * 
556 * @param tag
557 *    The tag is for your convenience.
558 *    It is not sent or received over the socket in any manner what-so-ever.
559 *    It is reported back as a parameter in the udpSocket:didSendDataWithTag:
560 *    or udpSocket:didNotSendDataWithTag:dueToError: methods.
561 *    You can use it as an array index, state id, type constant, etc.
562 * 
563 * 
564 * Thread-Safety Note:
565 * If the given data parameter is mutable (NSMutableData) then you MUST NOT alter the data while
566 * the socket is sending it. In other words, it's not safe to alter the data until after the delegate method
567 * udpSocket:didSendDataWithTag: or udpSocket:didNotSendDataWithTag:dueToError: is invoked signifying
568 * that this particular send operation has completed.
569 * This is due to the fact that GCDAsyncUdpSocket does NOT copy the data.
570 * It simply retains it for performance reasons.
571 * Often times, if NSMutableData is passed, it is because a request/response was built up in memory.
572 * Copying this data adds an unwanted/unneeded overhead.
573 * If you need to write data from an immutable buffer, and you need to alter the buffer before the socket
574 * completes sending the bytes (which is NOT immediately after this method returns, but rather at a later time
575 * when the delegate method notifies you), then you should first copy the bytes, and pass the copy to this method.
576**/
577- (void)sendData:(NSData *)data toAddress:(NSData *)remoteAddr withTimeout:(NSTimeInterval)timeout tag:(long)tag;
578
579/**
580 * You may optionally set a send filter for the socket.
581 * A filter can provide several interesting possibilities:
582 * 
583 * 1. Optional caching of resolved addresses for domain names.
584 *    The cache could later be consulted, resulting in fewer system calls to getaddrinfo.
585 * 
586 * 2. Reusable modules of code for bandwidth monitoring.
587 * 
588 * 3. Sometimes traffic shapers are needed to simulate real world environments.
589 *    A filter allows you to write custom code to simulate such environments.
590 *    The ability to code this yourself is especially helpful when your simulated environment
591 *    is more complicated than simple traffic shaping (e.g. simulating a cone port restricted router),
592 *    or the system tools to handle this aren't available (e.g. on a mobile device).
593 * 
594 * For more information about GCDAsyncUdpSocketSendFilterBlock, see the documentation for its typedef.
595 * To remove a previously set filter, invoke this method and pass a nil filterBlock and NULL filterQueue.
596 * 
597 * Note: This method invokes setSendFilter:withQueue:isAsynchronous: (documented below),
598 *       passing YES for the isAsynchronous parameter.
599**/
600- (void)setSendFilter:(GCDAsyncUdpSocketSendFilterBlock)filterBlock withQueue:(dispatch_queue_t)filterQueue;
601
602/**
603 * The receive filter can be run via dispatch_async or dispatch_sync.
604 * Most typical situations call for asynchronous operation.
605 * 
606 * However, there are a few situations in which synchronous operation is preferred.
607 * Such is the case when the filter is extremely minimal and fast.
608 * This is because dispatch_sync is faster than dispatch_async.
609 * 
610 * If you choose synchronous operation, be aware of possible deadlock conditions.
611 * Since the socket queue is executing your block via dispatch_sync,
612 * then you cannot perform any tasks which may invoke dispatch_sync on the socket queue.
613 * For example, you can't query properties on the socket.
614**/
615- (void)setSendFilter:(GCDAsyncUdpSocketSendFilterBlock)filterBlock
616            withQueue:(dispatch_queue_t)filterQueue
617       isAsynchronous:(BOOL)isAsynchronous;
618
619#pragma mark Receiving
620
621/**
622 * There are two modes of operation for receiving packets: one-at-a-time & continuous.
623 * 
624 * In one-at-a-time mode, you call receiveOnce everytime your delegate is ready to process an incoming udp packet.
625 * Receiving packets one-at-a-time may be better suited for implementing certain state machine code,
626 * where your state machine may not always be ready to process incoming packets.
627 * 
628 * In continuous mode, the delegate is invoked immediately everytime incoming udp packets are received.
629 * Receiving packets continuously is better suited to real-time streaming applications.
630 * 
631 * You may switch back and forth between one-at-a-time mode and continuous mode.
632 * If the socket is currently in continuous mode, calling this method will switch it to one-at-a-time mode.
633 * 
634 * When a packet is received (and not filtered by the optional receive filter),
635 * the delegate method (udpSocket:didReceiveData:fromAddress:withFilterContext:) is invoked.
636 * 
637 * If the socket is able to begin receiving packets, this method returns YES.
638 * Otherwise it returns NO, and sets the errPtr with appropriate error information.
639 * 
640 * An example error:
641 * You created a udp socket to act as a server, and immediately called receive.
642 * You forgot to first bind the socket to a port number, and received a error with a message like:
643 * "Must bind socket before you can receive data."
644**/
645- (BOOL)receiveOnce:(NSError **)errPtr;
646
647/**
648 * There are two modes of operation for receiving packets: one-at-a-time & continuous.
649 * 
650 * In one-at-a-time mode, you call receiveOnce everytime your delegate is ready to process an incoming udp packet.
651 * Receiving packets one-at-a-time may be better suited for implementing certain state machine code,
652 * where your state machine may not always be ready to process incoming packets.
653 * 
654 * In continuous mode, the delegate is invoked immediately everytime incoming udp packets are received.
655 * Receiving packets continuously is better suited to real-time streaming applications.
656 * 
657 * You may switch back and forth between one-at-a-time mode and continuous mode.
658 * If the socket is currently in one-at-a-time mode, calling this method will switch it to continuous mode.
659 * 
660 * For every received packet (not filtered by the optional receive filter),
661 * the delegate method (udpSocket:didReceiveData:fromAddress:withFilterContext:) is invoked.
662 * 
663 * If the socket is able to begin receiving packets, this method returns YES.
664 * Otherwise it returns NO, and sets the errPtr with appropriate error information.
665 * 
666 * An example error:
667 * You created a udp socket to act as a server, and immediately called receive.
668 * You forgot to first bind the socket to a port number, and received a error with a message like:
669 * "Must bind socket before you can receive data."
670**/
671- (BOOL)beginReceiving:(NSError **)errPtr;
672
673/**
674 * If the socket is currently receiving (beginReceiving has been called), this method pauses the receiving.
675 * That is, it won't read any more packets from the underlying OS socket until beginReceiving is called again.
676 * 
677 * Important Note:
678 * GCDAsyncUdpSocket may be running in parallel with your code.
679 * That is, your delegate is likely running on a separate thread/dispatch_queue.
680 * When you invoke this method, GCDAsyncUdpSocket may have already dispatched delegate methods to be invoked.
681 * Thus, if those delegate methods have already been dispatch_async'd,
682 * your didReceive delegate method may still be invoked after this method has been called.
683 * You should be aware of this, and program defensively.
684**/
685- (void)pauseReceiving;
686
687/**
688 * You may optionally set a receive filter for the socket.
689 * This receive filter may be set to run in its own queue (independent of delegate queue).
690 * 
691 * A filter can provide several useful features.
692 * 
693 * 1. Many times udp packets need to be parsed.
694 *    Since the filter can run in its own independent queue, you can parallelize this parsing quite easily.
695 *    The end result is a parallel socket io, datagram parsing, and packet processing.
696 * 
697 * 2. Many times udp packets are discarded because they are duplicate/unneeded/unsolicited.
698 *    The filter can prevent such packets from arriving at the delegate.
699 *    And because the filter can run in its own independent queue, this doesn't slow down the delegate.
700 * 
701 *    - Since the udp protocol does not guarantee delivery, udp packets may be lost.
702 *      Many protocols built atop udp thus provide various resend/re-request algorithms.
703 *      This sometimes results in duplicate packets arriving.
704 *      A filter may allow you to architect the duplicate detection code to run in parallel to normal processing.
705 *    
706 *    - Since the udp socket may be connectionless, its possible for unsolicited packets to arrive.
707 *      Such packets need to be ignored.
708 * 
709 * 3. Sometimes traffic shapers are needed to simulate real world environments.
710 *    A filter allows you to write custom code to simulate such environments.
711 *    The ability to code this yourself is especially helpful when your simulated environment
712 *    is more complicated than simple traffic shaping (e.g. simulating a cone port restricted router),
713 *    or the system tools to handle this aren't available (e.g. on a mobile device).
714 * 
715 * Example:
716 * 
717 * GCDAsyncUdpSocketReceiveFilterBlock filter = ^BOOL (NSData *data, NSData *address, id *context) {
718 * 
719 *     MyProtocolMessage *msg = [MyProtocol parseMessage:data];
720 *     
721 *     *context = response;
722 *     return (response != nil);
723 * };
724 * [udpSocket setReceiveFilter:filter withQueue:myParsingQueue];
725 * 
726 * For more information about GCDAsyncUdpSocketReceiveFilterBlock, see the documentation for its typedef.
727 * To remove a previously set filter, invoke this method and pass a nil filterBlock and NULL filterQueue.
728 * 
729 * Note: This method invokes setReceiveFilter:withQueue:isAsynchronous: (documented below),
730 *       passing YES for the isAsynchronous parameter.
731**/
732- (void)setReceiveFilter:(GCDAsyncUdpSocketReceiveFilterBlock)filterBlock withQueue:(dispatch_queue_t)filterQueue;
733
734/**
735 * The receive filter can be run via dispatch_async or dispatch_sync.
736 * Most typical situations call for asynchronous operation.
737 * 
738 * However, there are a few situations in which synchronous operation is preferred.
739 * Such is the case when the filter is extremely minimal and fast.
740 * This is because dispatch_sync is faster than dispatch_async.
741 * 
742 * If you choose synchronous operation, be aware of possible deadlock conditions.
743 * Since the socket queue is executing your block via dispatch_sync,
744 * then you cannot perform any tasks which may invoke dispatch_sync on the socket queue.
745 * For example, you can't query properties on the socket.
746**/
747- (void)setReceiveFilter:(GCDAsyncUdpSocketReceiveFilterBlock)filterBlock
748               withQueue:(dispatch_queue_t)filterQueue
749          isAsynchronous:(BOOL)isAsynchronous;
750
751#pragma mark Closing
752
753/**
754 * Immediately closes the underlying socket.
755 * Any pending send operations are discarded.
756 * 
757 * The GCDAsyncUdpSocket instance may optionally be used again.
758 *   (it will setup/configure/use another unnderlying BSD socket).
759**/
760- (void)close;
761
762/**
763 * Closes the underlying socket after all pending send operations have been sent.
764 * 
765 * The GCDAsyncUdpSocket instance may optionally be used again.
766 *   (it will setup/configure/use another unnderlying BSD socket).
767**/
768- (void)closeAfterSending;
769
770#pragma mark Advanced
771/**
772 * GCDAsyncSocket maintains thread safety by using an internal serial dispatch_queue.
773 * In most cases, the instance creates this queue itself.
774 * However, to allow for maximum flexibility, the internal queue may be passed in the init method.
775 * This allows for some advanced options such as controlling socket priority via target queues.
776 * However, when one begins to use target queues like this, they open the door to some specific deadlock issues.
777 *
778 * For example, imagine there are 2 queues:
779 * dispatch_queue_t socketQueue;
780 * dispatch_queue_t socketTargetQueue;
781 *
782 * If you do this (pseudo-code):
783 * socketQueue.targetQueue = socketTargetQueue;
784 *
785 * Then all socketQueue operations will actually get run on the given socketTargetQueue.
786 * This is fine and works great in most situations.
787 * But if you run code directly from within the socketTargetQueue that accesses the socket,
788 * you could potentially get deadlock. Imagine the following code:
789 *
790 * - (BOOL)socketHasSomething
791 * {
792 *     __block BOOL result = NO;
793 *     dispatch_block_t block = ^{
794 *         result = [self someInternalMethodToBeRunOnlyOnSocketQueue];
795 *     }
796 *     if (is_executing_on_queue(socketQueue))
797 *         block();
798 *     else
799 *         dispatch_sync(socketQueue, block);
800 *
801 *     return result;
802 * }
803 *
804 * What happens if you call this method from the socketTargetQueue? The result is deadlock.
805 * This is because the GCD API offers no mechanism to discover a queue's targetQueue.
806 * Thus we have no idea if our socketQueue is configured with a targetQueue.
807 * If we had this information, we could easily avoid deadlock.
808 * But, since these API's are missing or unfeasible, you'll have to explicitly set it.
809 *
810 * IF you pass a socketQueue via the init method,
811 * AND you've configured the passed socketQueue with a targetQueue,
812 * THEN you should pass the end queue in the target hierarchy.
813 *
814 * For example, consider the following queue hierarchy:
815 * socketQueue -> ipQueue -> moduleQueue
816 *
817 * This example demonstrates priority shaping within some server.
818 * All incoming client connections from the same IP address are executed on the same target queue.
819 * And all connections for a particular module are executed on the same target queue.
820 * Thus, the priority of all networking for the entire module can be changed on the fly.
821 * Additionally, networking traffic from a single IP cannot monopolize the module.
822 *
823 * Here's how you would accomplish something like that:
824 * - (dispatch_queue_t)newSocketQueueForConnectionFromAddress:(NSData *)address onSocket:(GCDAsyncSocket *)sock
825 * {
826 *     dispatch_queue_t socketQueue = dispatch_queue_create("", NULL);
827 *     dispatch_queue_t ipQueue = [self ipQueueForAddress:address];
828 *
829 *     dispatch_set_target_queue(socketQueue, ipQueue);
830 *     dispatch_set_target_queue(iqQueue, moduleQueue);
831 *
832 *     return socketQueue;
833 * }
834 * - (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
835 * {
836 *     [clientConnections addObject:newSocket];
837 *     [newSocket markSocketQueueTargetQueue:moduleQueue];
838 * }
839 *
840 * Note: This workaround is ONLY needed if you intend to execute code directly on the ipQueue or moduleQueue.
841 * This is often NOT the case, as such queues are used solely for execution shaping.
842 **/
843- (void)markSocketQueueTargetQueue:(dispatch_queue_t)socketQueuesPreConfiguredTargetQueue;
844- (void)unmarkSocketQueueTargetQueue:(dispatch_queue_t)socketQueuesPreviouslyConfiguredTargetQueue;
845
846/**
847 * It's not thread-safe to access certain variables from outside the socket's internal queue.
848 * 
849 * For example, the socket file descriptor.
850 * File descriptors are simply integers which reference an index in the per-process file table.
851 * However, when one requests a new file descriptor (by opening a file or socket),
852 * the file descriptor returned is guaranteed to be the lowest numbered unused descriptor.
853 * So if we're not careful, the following could be possible:
854 * 
855 * - Thread A invokes a method which returns the socket's file descriptor.
856 * - The socket is closed via the socket's internal queue on thread B.
857 * - Thread C opens a file, and subsequently receives the file descriptor that was previously the socket's FD.
858 * - Thread A is now accessing/altering the file instead of the socket.
859 * 
860 * In addition to this, other variables are not actually objects,
861 * and thus cannot be retained/released or even autoreleased.
862 * An example is the sslContext, of type SSLContextRef, which is actually a malloc'd struct.
863 * 
864 * Although there are internal variables that make it difficult to maintain thread-safety,
865 * it is important to provide access to these variables
866 * to ensure this class can be used in a wide array of environments.
867 * This method helps to accomplish this by invoking the current block on the socket's internal queue.
868 * The methods below can be invoked from within the block to access
869 * those generally thread-unsafe internal variables in a thread-safe manner.
870 * The given block will be invoked synchronously on the socket's internal queue.
871 * 
872 * If you save references to any protected variables and use them outside the block, you do so at your own peril.
873**/
874- (void)performBlock:(dispatch_block_t)block;
875
876/**
877 * These methods are only available from within the context of a performBlock: invocation.
878 * See the documentation for the performBlock: method above.
879 * 
880 * Provides access to the socket's file descriptor(s).
881 * If the socket isn't connected, or explicity bound to a particular interface,
882 * it might actually have multiple internal socket file descriptors - one for IPv4 and one for IPv6.
883**/
884- (int)socketFD;
885- (int)socket4FD;
886- (int)socket6FD;
887
888#if TARGET_OS_IPHONE
889
890/**
891 * These methods are only available from within the context of a performBlock: invocation.
892 * See the documentation for the performBlock: method above.
893 * 
894 * Returns (creating if necessary) a CFReadStream/CFWriteStream for the internal socket.
895 * 
896 * Generally GCDAsyncUdpSocket doesn't use CFStream. (It uses the faster GCD API's.)
897 * However, if you need one for any reason,
898 * these methods are a convenient way to get access to a safe instance of one.
899**/
900- (CFReadStreamRef)readStream;
901- (CFWriteStreamRef)writeStream;
902
903/**
904 * This method is only available from within the context of a performBlock: invocation.
905 * See the documentation for the performBlock: method above.
906 * 
907 * Configures the socket to allow it to operate when the iOS application has been backgrounded.
908 * In other words, this method creates a read & write stream, and invokes:
909 * 
910 * CFReadStreamSetProperty(readStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
911 * CFWriteStreamSetProperty(writeStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
912 * 
913 * Returns YES if successful, NO otherwise.
914 * 
915 * Example usage:
916 * 
917 * [asyncUdpSocket performBlock:^{
918 *     [asyncUdpSocket enableBackgroundingOnSocket];
919 * }];
920 * 
921 * 
922 * NOTE : Apple doesn't currently support backgrounding UDP sockets. (Only TCP for now).
923**/
924//- (BOOL)enableBackgroundingOnSockets;
925
926#endif
927
928#pragma mark Utilities
929
930/**
931 * Extracting host/port/family information from raw address data.
932**/
933
934+ (NSString *)hostFromAddress:(NSData *)address;
935+ (uint16_t)portFromAddress:(NSData *)address;
936+ (int)familyFromAddress:(NSData *)address;
937
938+ (BOOL)isIPv4Address:(NSData *)address;
939+ (BOOL)isIPv6Address:(NSData *)address;
940
941+ (BOOL)getHost:(NSString **)hostPtr port:(uint16_t *)portPtr fromAddress:(NSData *)address;
942+ (BOOL)getHost:(NSString **)hostPtr port:(uint16_t *)portPtr family:(int *)afPtr fromAddress:(NSData *)address;
943
944@end
945
946////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
947#pragma mark -
948////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
949
950@protocol GCDAsyncUdpSocketDelegate
951@optional
952
953/**
954 * By design, UDP is a connectionless protocol, and connecting is not needed.
955 * However, you may optionally choose to connect to a particular host for reasons
956 * outlined in the documentation for the various connect methods listed above.
957 * 
958 * This method is called if one of the connect methods are invoked, and the connection is successful.
959**/
960- (void)udpSocket:(GCDAsyncUdpSocket *)sock didConnectToAddress:(NSData *)address;
961
962/**
963 * By design, UDP is a connectionless protocol, and connecting is not needed.
964 * However, you may optionally choose to connect to a particular host for reasons
965 * outlined in the documentation for the various connect methods listed above.
966 * 
967 * This method is called if one of the connect methods are invoked, and the connection fails.
968 * This may happen, for example, if a domain name is given for the host and the domain name is unable to be resolved.
969**/
970- (void)udpSocket:(GCDAsyncUdpSocket *)sock didNotConnect:(NSError *)error;
971
972/**
973 * Called when the datagram with the given tag has been sent.
974**/
975- (void)udpSocket:(GCDAsyncUdpSocket *)sock didSendDataWithTag:(long)tag;
976
977/**
978 * Called if an error occurs while trying to send a datagram.
979 * This could be due to a timeout, or something more serious such as the data being too large to fit in a sigle packet.
980**/
981- (void)udpSocket:(GCDAsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError *)error;
982
983/**
984 * Called when the socket has received the requested datagram.
985**/
986- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data
987                                             fromAddress:(NSData *)address
988                                       withFilterContext:(id)filterContext;
989
990/**
991 * Called when the socket is closed.
992**/
993- (void)udpSocketDidClose:(GCDAsyncUdpSocket *)sock withError:(NSError *)error;
994
995@end
996