/Vendor/AsyncSocket/GCDAsyncUdpSocket.h
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