PageRenderTime 47ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/Pods/Headers/CocoaAsyncSocket/GCDAsyncUdpSocket.h

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