/GCD/GCDAsyncUdpSocket.h

https://github.com/coderlirui/CocoaAsyncSocket · C Header · 996 lines · 137 code · 80 blank · 779 comment · 0 complexity · 8318f4d9a793af3d9c3e8de1980fca22 MD5 · raw file

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