PageRenderTime 24ms CodeModel.GetById 2ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 1ms

/Vendor/AsyncSocket/GCDAsyncUdpSocket.h

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