init
This commit is contained in:
parent
59be67ccb6
commit
9d81a6cbaf
BIN
ios/Framework/CocoaAsyncSocket.framework/CocoaAsyncSocket
Normal file
BIN
ios/Framework/CocoaAsyncSocket.framework/CocoaAsyncSocket
Normal file
Binary file not shown.
657
ios/Framework/CocoaAsyncSocket.framework/Headers/AsyncSocket.h
Normal file
657
ios/Framework/CocoaAsyncSocket.framework/Headers/AsyncSocket.h
Normal file
@ -0,0 +1,657 @@
|
|||||||
|
//
|
||||||
|
// AsyncSocket.h
|
||||||
|
//
|
||||||
|
// This class is in the public domain.
|
||||||
|
// Originally created by Dustin Voss on Wed Jan 29 2003.
|
||||||
|
// Updated and maintained by Deusty Designs and the Mac development community.
|
||||||
|
//
|
||||||
|
// http://code.google.com/p/cocoaasyncsocket/
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
@class AsyncSocket;
|
||||||
|
@class AsyncReadPacket;
|
||||||
|
@class AsyncWritePacket;
|
||||||
|
|
||||||
|
extern NSString *const AsyncSocketException;
|
||||||
|
extern NSString *const AsyncSocketErrorDomain;
|
||||||
|
|
||||||
|
typedef NS_ENUM(NSInteger, AsyncSocketError) {
|
||||||
|
AsyncSocketCFSocketError = kCFSocketError, // From CFSocketError enum.
|
||||||
|
AsyncSocketNoError = 0, // Never used.
|
||||||
|
AsyncSocketCanceledError, // onSocketWillConnect: returned NO.
|
||||||
|
AsyncSocketConnectTimeoutError,
|
||||||
|
AsyncSocketReadMaxedOutError, // Reached set maxLength without completing
|
||||||
|
AsyncSocketReadTimeoutError,
|
||||||
|
AsyncSocketWriteTimeoutError
|
||||||
|
};
|
||||||
|
|
||||||
|
@protocol AsyncSocketDelegate
|
||||||
|
@optional
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In the event of an error, the socket is closed.
|
||||||
|
* You may call "unreadData" during this call-back to get the last bit of data off the socket.
|
||||||
|
* When connecting, this delegate method may be called
|
||||||
|
* before"onSocket:didAcceptNewSocket:" or "onSocket:didConnectToHost:".
|
||||||
|
**/
|
||||||
|
- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a socket disconnects with or without error. If you want to release a socket after it disconnects,
|
||||||
|
* do so here. It is not safe to do that during "onSocket:willDisconnectWithError:".
|
||||||
|
*
|
||||||
|
* If you call the disconnect method, and the socket wasn't already disconnected,
|
||||||
|
* this delegate method will be called before the disconnect method returns.
|
||||||
|
**/
|
||||||
|
- (void)onSocketDidDisconnect:(AsyncSocket *)sock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a socket accepts a connection. Another socket is spawned to handle it. The new socket will have
|
||||||
|
* the same delegate and will call "onSocket:didConnectToHost:port:".
|
||||||
|
**/
|
||||||
|
- (void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a new socket is spawned to handle a connection. This method should return the run-loop of the
|
||||||
|
* thread on which the new socket and its delegate should operate. If omitted, [NSRunLoop currentRunLoop] is used.
|
||||||
|
**/
|
||||||
|
- (NSRunLoop *)onSocket:(AsyncSocket *)sock wantsRunLoopForNewSocket:(AsyncSocket *)newSocket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a socket is about to connect. This method should return YES to continue, or NO to abort.
|
||||||
|
* If aborted, will result in AsyncSocketCanceledError.
|
||||||
|
*
|
||||||
|
* If the connectToHost:onPort:error: method was called, the delegate will be able to access and configure the
|
||||||
|
* CFReadStream and CFWriteStream as desired prior to connection.
|
||||||
|
*
|
||||||
|
* If the connectToAddress:error: method was called, the delegate will be able to access and configure the
|
||||||
|
* CFSocket and CFSocketNativeHandle (BSD socket) as desired prior to connection. You will be able to access and
|
||||||
|
* configure the CFReadStream and CFWriteStream in the onSocket:didConnectToHost:port: method.
|
||||||
|
**/
|
||||||
|
- (BOOL)onSocketWillConnect:(AsyncSocket *)sock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a socket connects and is ready for reading and writing.
|
||||||
|
* The host parameter will be an IP address, not a DNS name.
|
||||||
|
**/
|
||||||
|
- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a socket has completed reading the requested data into memory.
|
||||||
|
* Not called if there is an error.
|
||||||
|
**/
|
||||||
|
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a socket has read in data, but has not yet completed the read.
|
||||||
|
* This would occur if using readToData: or readToLength: methods.
|
||||||
|
* It may be used to for things such as updating progress bars.
|
||||||
|
**/
|
||||||
|
- (void)onSocket:(AsyncSocket *)sock didReadPartialDataOfLength:(NSUInteger)partialLength tag:(long)tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a socket has completed writing the requested data. Not called if there is an error.
|
||||||
|
**/
|
||||||
|
- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a socket has written some data, but has not yet completed the entire write.
|
||||||
|
* It may be used to for things such as updating progress bars.
|
||||||
|
**/
|
||||||
|
- (void)onSocket:(AsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called if a read operation has reached its timeout without completing.
|
||||||
|
* This method allows you to optionally extend the timeout.
|
||||||
|
* If you return a positive time interval (> 0) the read's timeout will be extended by the given amount.
|
||||||
|
* If you don't implement this method, or return a non-positive time interval (<= 0) the read will timeout as usual.
|
||||||
|
*
|
||||||
|
* The elapsed parameter is the sum of the original timeout, plus any additions previously added via this method.
|
||||||
|
* The length parameter is the number of bytes that have been read so far for the read operation.
|
||||||
|
*
|
||||||
|
* Note that this method may be called multiple times for a single read if you return positive numbers.
|
||||||
|
**/
|
||||||
|
- (NSTimeInterval)onSocket:(AsyncSocket *)sock
|
||||||
|
shouldTimeoutReadWithTag:(long)tag
|
||||||
|
elapsed:(NSTimeInterval)elapsed
|
||||||
|
bytesDone:(NSUInteger)length;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called if a write operation has reached its timeout without completing.
|
||||||
|
* This method allows you to optionally extend the timeout.
|
||||||
|
* If you return a positive time interval (> 0) the write's timeout will be extended by the given amount.
|
||||||
|
* If you don't implement this method, or return a non-positive time interval (<= 0) the write will timeout as usual.
|
||||||
|
*
|
||||||
|
* The elapsed parameter is the sum of the original timeout, plus any additions previously added via this method.
|
||||||
|
* The length parameter is the number of bytes that have been written so far for the write operation.
|
||||||
|
*
|
||||||
|
* Note that this method may be called multiple times for a single write if you return positive numbers.
|
||||||
|
**/
|
||||||
|
- (NSTimeInterval)onSocket:(AsyncSocket *)sock
|
||||||
|
shouldTimeoutWriteWithTag:(long)tag
|
||||||
|
elapsed:(NSTimeInterval)elapsed
|
||||||
|
bytesDone:(NSUInteger)length;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after the socket has successfully completed SSL/TLS negotiation.
|
||||||
|
* This method is not called unless you use the provided startTLS method.
|
||||||
|
*
|
||||||
|
* If a SSL/TLS negotiation fails (invalid certificate, etc) then the socket will immediately close,
|
||||||
|
* and the onSocket:willDisconnectWithError: delegate method will be called with the specific SSL error code.
|
||||||
|
**/
|
||||||
|
- (void)onSocketDidSecure:(AsyncSocket *)sock;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#pragma mark -
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@interface AsyncSocket : NSObject
|
||||||
|
{
|
||||||
|
CFSocketNativeHandle theNativeSocket4;
|
||||||
|
CFSocketNativeHandle theNativeSocket6;
|
||||||
|
|
||||||
|
CFSocketRef theSocket4; // IPv4 accept or connect socket
|
||||||
|
CFSocketRef theSocket6; // IPv6 accept or connect socket
|
||||||
|
|
||||||
|
CFReadStreamRef theReadStream;
|
||||||
|
CFWriteStreamRef theWriteStream;
|
||||||
|
|
||||||
|
CFRunLoopSourceRef theSource4; // For theSocket4
|
||||||
|
CFRunLoopSourceRef theSource6; // For theSocket6
|
||||||
|
CFRunLoopRef theRunLoop;
|
||||||
|
CFSocketContext theContext;
|
||||||
|
NSArray *theRunLoopModes;
|
||||||
|
|
||||||
|
NSTimer *theConnectTimer;
|
||||||
|
|
||||||
|
NSMutableArray *theReadQueue;
|
||||||
|
AsyncReadPacket *theCurrentRead;
|
||||||
|
NSTimer *theReadTimer;
|
||||||
|
NSMutableData *partialReadBuffer;
|
||||||
|
|
||||||
|
NSMutableArray *theWriteQueue;
|
||||||
|
AsyncWritePacket *theCurrentWrite;
|
||||||
|
NSTimer *theWriteTimer;
|
||||||
|
|
||||||
|
id theDelegate;
|
||||||
|
UInt16 theFlags;
|
||||||
|
|
||||||
|
long theUserData;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)init;
|
||||||
|
- (id)initWithDelegate:(id)delegate;
|
||||||
|
- (id)initWithDelegate:(id)delegate userData:(long)userData;
|
||||||
|
|
||||||
|
/* String representation is long but has no "\n". */
|
||||||
|
- (NSString *)description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use "canSafelySetDelegate" to see if there is any pending business (reads and writes) with the current delegate
|
||||||
|
* before changing it. It is, of course, safe to change the delegate before connecting or accepting connections.
|
||||||
|
**/
|
||||||
|
- (id)delegate;
|
||||||
|
- (BOOL)canSafelySetDelegate;
|
||||||
|
- (void)setDelegate:(id)delegate;
|
||||||
|
|
||||||
|
/* User data can be a long, or an id or void * cast to a long. */
|
||||||
|
- (long)userData;
|
||||||
|
- (void)setUserData:(long)userData;
|
||||||
|
|
||||||
|
/* Don't use these to read or write. And don't close them either! */
|
||||||
|
- (CFSocketRef)getCFSocket;
|
||||||
|
- (CFReadStreamRef)getCFReadStream;
|
||||||
|
- (CFWriteStreamRef)getCFWriteStream;
|
||||||
|
|
||||||
|
// Once one of the accept or connect methods are called, the AsyncSocket instance is locked in
|
||||||
|
// and the other accept/connect methods can't be called without disconnecting the socket first.
|
||||||
|
// If the attempt fails or times out, these methods either return NO or
|
||||||
|
// call "onSocket:willDisconnectWithError:" and "onSockedDidDisconnect:".
|
||||||
|
|
||||||
|
// When an incoming connection is accepted, AsyncSocket invokes several delegate methods.
|
||||||
|
// These methods are (in chronological order):
|
||||||
|
// 1. onSocket:didAcceptNewSocket:
|
||||||
|
// 2. onSocket:wantsRunLoopForNewSocket:
|
||||||
|
// 3. onSocketWillConnect:
|
||||||
|
//
|
||||||
|
// Your server code will need to retain the accepted socket (if you want to accept it).
|
||||||
|
// The best place to do this is probably in the onSocket:didAcceptNewSocket: method.
|
||||||
|
//
|
||||||
|
// After the read and write streams have been setup for the newly accepted socket,
|
||||||
|
// the onSocket:didConnectToHost:port: method will be called on the proper run loop.
|
||||||
|
//
|
||||||
|
// Multithreading Note: If you're going to be moving the newly accepted socket to another run
|
||||||
|
// loop by implementing onSocket:wantsRunLoopForNewSocket:, then you should wait until the
|
||||||
|
// onSocket:didConnectToHost:port: method before calling read, write, or startTLS methods.
|
||||||
|
// Otherwise read/write events are scheduled on the incorrect runloop, and chaos may ensue.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells the socket to begin listening and accepting connections on the given port.
|
||||||
|
* When a connection comes in, the AsyncSocket instance will call the various delegate methods (see above).
|
||||||
|
* The socket will listen on all available interfaces (e.g. wifi, ethernet, etc)
|
||||||
|
**/
|
||||||
|
- (BOOL)acceptOnPort:(UInt16)port error:(NSError **)errPtr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is the same as acceptOnPort:error: with the additional option
|
||||||
|
* of specifying which interface to listen on. So, for example, if you were writing code for a server that
|
||||||
|
* has multiple IP addresses, you could specify which address you wanted to listen on. Or you could use it
|
||||||
|
* to specify that the socket should only accept connections over ethernet, and not other interfaces such as wifi.
|
||||||
|
* You may also use the special strings "localhost" or "loopback" to specify that
|
||||||
|
* the socket only accept connections from the local machine.
|
||||||
|
*
|
||||||
|
* To accept connections on any interface pass nil, or simply use the acceptOnPort:error: method.
|
||||||
|
**/
|
||||||
|
- (BOOL)acceptOnInterface:(NSString *)interface port:(UInt16)port error:(NSError **)errPtr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects to the given host and port.
|
||||||
|
* The host may be a domain name (e.g. "deusty.com") or an IP address string (e.g. "192.168.0.2")
|
||||||
|
**/
|
||||||
|
- (BOOL)connectToHost:(NSString *)hostname onPort:(UInt16)port error:(NSError **)errPtr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is the same as connectToHost:onPort:error: with an additional timeout option.
|
||||||
|
* To not time out use a negative time interval, or simply use the connectToHost:onPort:error: method.
|
||||||
|
**/
|
||||||
|
- (BOOL)connectToHost:(NSString *)hostname
|
||||||
|
onPort:(UInt16)port
|
||||||
|
withTimeout:(NSTimeInterval)timeout
|
||||||
|
error:(NSError **)errPtr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects to the given address, specified as a sockaddr structure wrapped in a NSData object.
|
||||||
|
* For example, a NSData object returned from NSNetService's addresses method.
|
||||||
|
*
|
||||||
|
* If you have an existing struct sockaddr you can convert it to a NSData object like so:
|
||||||
|
* struct sockaddr sa -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len];
|
||||||
|
* struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len];
|
||||||
|
**/
|
||||||
|
- (BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError **)errPtr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is the same as connectToAddress:error: with an additional timeout option.
|
||||||
|
* To not time out use a negative time interval, or simply use the connectToAddress:error: method.
|
||||||
|
**/
|
||||||
|
- (BOOL)connectToAddress:(NSData *)remoteAddr withTimeout:(NSTimeInterval)timeout error:(NSError **)errPtr;
|
||||||
|
|
||||||
|
- (BOOL)connectToAddress:(NSData *)remoteAddr
|
||||||
|
viaInterfaceAddress:(NSData *)interfaceAddr
|
||||||
|
withTimeout:(NSTimeInterval)timeout
|
||||||
|
error:(NSError **)errPtr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects immediately. Any pending reads or writes are dropped.
|
||||||
|
* If the socket is not already disconnected, the onSocketDidDisconnect delegate method
|
||||||
|
* will be called immediately, before this method returns.
|
||||||
|
*
|
||||||
|
* Please note the recommended way of releasing an AsyncSocket instance (e.g. in a dealloc method)
|
||||||
|
* [asyncSocket setDelegate:nil];
|
||||||
|
* [asyncSocket disconnect];
|
||||||
|
* [asyncSocket release];
|
||||||
|
**/
|
||||||
|
- (void)disconnect;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects after all pending reads have completed.
|
||||||
|
* After calling this, the read and write methods will do nothing.
|
||||||
|
* The socket will disconnect even if there are still pending writes.
|
||||||
|
**/
|
||||||
|
- (void)disconnectAfterReading;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects after all pending writes have completed.
|
||||||
|
* After calling this, the read and write methods will do nothing.
|
||||||
|
* The socket will disconnect even if there are still pending reads.
|
||||||
|
**/
|
||||||
|
- (void)disconnectAfterWriting;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects after all pending reads and writes have completed.
|
||||||
|
* After calling this, the read and write methods will do nothing.
|
||||||
|
**/
|
||||||
|
- (void)disconnectAfterReadingAndWriting;
|
||||||
|
|
||||||
|
/* Returns YES if the socket and streams are open, connected, and ready for reading and writing. */
|
||||||
|
- (BOOL)isConnected;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the local or remote host and port to which this socket is connected, or nil and 0 if not connected.
|
||||||
|
* The host will be an IP address.
|
||||||
|
**/
|
||||||
|
- (NSString *)connectedHost;
|
||||||
|
- (UInt16)connectedPort;
|
||||||
|
|
||||||
|
- (NSString *)localHost;
|
||||||
|
- (UInt16)localPort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the local or remote address to which this socket is connected,
|
||||||
|
* specified as a sockaddr structure wrapped in a NSData object.
|
||||||
|
*
|
||||||
|
* See also the connectedHost, connectedPort, localHost and localPort methods.
|
||||||
|
**/
|
||||||
|
- (NSData *)connectedAddress;
|
||||||
|
- (NSData *)localAddress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the socket is IPv4 or IPv6.
|
||||||
|
* An accepting socket may be both.
|
||||||
|
**/
|
||||||
|
- (BOOL)isIPv4;
|
||||||
|
- (BOOL)isIPv6;
|
||||||
|
|
||||||
|
// The readData and writeData methods won't block (they are asynchronous).
|
||||||
|
//
|
||||||
|
// When a read is complete the onSocket:didReadData:withTag: delegate method is called.
|
||||||
|
// When a write is complete the onSocket:didWriteDataWithTag: delegate method is called.
|
||||||
|
//
|
||||||
|
// You may optionally set a timeout for any read/write operation. (To not timeout, use a negative time interval.)
|
||||||
|
// If a read/write opertion times out, the corresponding "onSocket:shouldTimeout..." delegate method
|
||||||
|
// is called to optionally allow you to extend the timeout.
|
||||||
|
// Upon a timeout, the "onSocket:willDisconnectWithError:" method is called, followed by "onSocketDidDisconnect".
|
||||||
|
//
|
||||||
|
// The tag is for your convenience.
|
||||||
|
// You can use it as an array index, step number, state id, pointer, etc.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the first available bytes that become available on the socket.
|
||||||
|
*
|
||||||
|
* If the timeout value is negative, the read operation will not use a timeout.
|
||||||
|
**/
|
||||||
|
- (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the first available bytes that become available on the socket.
|
||||||
|
* The bytes will be appended to the given byte buffer starting at the given offset.
|
||||||
|
* The given buffer will automatically be increased in size if needed.
|
||||||
|
*
|
||||||
|
* If the timeout value is negative, the read operation will not use a timeout.
|
||||||
|
* If the buffer if nil, the socket will create a buffer for you.
|
||||||
|
*
|
||||||
|
* If the bufferOffset is greater than the length of the given buffer,
|
||||||
|
* the method will do nothing, and the delegate will not be called.
|
||||||
|
*
|
||||||
|
* If you pass a buffer, you must not alter it in any way while AsyncSocket is using it.
|
||||||
|
* After completion, the data returned in onSocket:didReadData:withTag: will be a subset of the given buffer.
|
||||||
|
* That is, it will reference the bytes that were appended to the given buffer.
|
||||||
|
**/
|
||||||
|
- (void)readDataWithTimeout:(NSTimeInterval)timeout
|
||||||
|
buffer:(NSMutableData *)buffer
|
||||||
|
bufferOffset:(NSUInteger)offset
|
||||||
|
tag:(long)tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the first available bytes that become available on the socket.
|
||||||
|
* The bytes will be appended to the given byte buffer starting at the given offset.
|
||||||
|
* The given buffer will automatically be increased in size if needed.
|
||||||
|
* A maximum of length bytes will be read.
|
||||||
|
*
|
||||||
|
* If the timeout value is negative, the read operation will not use a timeout.
|
||||||
|
* If the buffer if nil, a buffer will automatically be created for you.
|
||||||
|
* If maxLength is zero, no length restriction is enforced.
|
||||||
|
*
|
||||||
|
* If the bufferOffset is greater than the length of the given buffer,
|
||||||
|
* the method will do nothing, and the delegate will not be called.
|
||||||
|
*
|
||||||
|
* If you pass a buffer, you must not alter it in any way while AsyncSocket is using it.
|
||||||
|
* After completion, the data returned in onSocket:didReadData:withTag: will be a subset of the given buffer.
|
||||||
|
* That is, it will reference the bytes that were appended to the given buffer.
|
||||||
|
**/
|
||||||
|
- (void)readDataWithTimeout:(NSTimeInterval)timeout
|
||||||
|
buffer:(NSMutableData *)buffer
|
||||||
|
bufferOffset:(NSUInteger)offset
|
||||||
|
maxLength:(NSUInteger)length
|
||||||
|
tag:(long)tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the given number of bytes.
|
||||||
|
*
|
||||||
|
* If the timeout value is negative, the read operation will not use a timeout.
|
||||||
|
*
|
||||||
|
* If the length is 0, this method does nothing and the delegate is not called.
|
||||||
|
**/
|
||||||
|
- (void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the given number of bytes.
|
||||||
|
* The bytes will be appended to the given byte buffer starting at the given offset.
|
||||||
|
* The given buffer will automatically be increased in size if needed.
|
||||||
|
*
|
||||||
|
* If the timeout value is negative, the read operation will not use a timeout.
|
||||||
|
* If the buffer if nil, a buffer will automatically be created for you.
|
||||||
|
*
|
||||||
|
* If the length is 0, this method does nothing and the delegate is not called.
|
||||||
|
* If the bufferOffset is greater than the length of the given buffer,
|
||||||
|
* the method will do nothing, and the delegate will not be called.
|
||||||
|
*
|
||||||
|
* If you pass a buffer, you must not alter it in any way while AsyncSocket is using it.
|
||||||
|
* After completion, the data returned in onSocket:didReadData:withTag: will be a subset of the given buffer.
|
||||||
|
* That is, it will reference the bytes that were appended to the given buffer.
|
||||||
|
**/
|
||||||
|
- (void)readDataToLength:(NSUInteger)length
|
||||||
|
withTimeout:(NSTimeInterval)timeout
|
||||||
|
buffer:(NSMutableData *)buffer
|
||||||
|
bufferOffset:(NSUInteger)offset
|
||||||
|
tag:(long)tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads bytes until (and including) the passed "data" parameter, which acts as a separator.
|
||||||
|
*
|
||||||
|
* If the timeout value is negative, the read operation will not use a timeout.
|
||||||
|
*
|
||||||
|
* If you pass nil or zero-length data as the "data" parameter,
|
||||||
|
* the method will do nothing, and the delegate will not be called.
|
||||||
|
*
|
||||||
|
* To read a line from the socket, use the line separator (e.g. CRLF for HTTP, see below) as the "data" parameter.
|
||||||
|
* Note that this method is not character-set aware, so if a separator can occur naturally as part of the encoding for
|
||||||
|
* a character, the read will prematurely end.
|
||||||
|
**/
|
||||||
|
- (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads bytes until (and including) the passed "data" parameter, which acts as a separator.
|
||||||
|
* The bytes will be appended to the given byte buffer starting at the given offset.
|
||||||
|
* The given buffer will automatically be increased in size if needed.
|
||||||
|
*
|
||||||
|
* If the timeout value is negative, the read operation will not use a timeout.
|
||||||
|
* If the buffer if nil, a buffer will automatically be created for you.
|
||||||
|
*
|
||||||
|
* If the bufferOffset is greater than the length of the given buffer,
|
||||||
|
* the method will do nothing, and the delegate will not be called.
|
||||||
|
*
|
||||||
|
* If you pass a buffer, you must not alter it in any way while AsyncSocket is using it.
|
||||||
|
* After completion, the data returned in onSocket:didReadData:withTag: will be a subset of the given buffer.
|
||||||
|
* That is, it will reference the bytes that were appended to the given buffer.
|
||||||
|
*
|
||||||
|
* To read a line from the socket, use the line separator (e.g. CRLF for HTTP, see below) as the "data" parameter.
|
||||||
|
* Note that this method is not character-set aware, so if a separator can occur naturally as part of the encoding for
|
||||||
|
* a character, the read will prematurely end.
|
||||||
|
**/
|
||||||
|
- (void)readDataToData:(NSData *)data
|
||||||
|
withTimeout:(NSTimeInterval)timeout
|
||||||
|
buffer:(NSMutableData *)buffer
|
||||||
|
bufferOffset:(NSUInteger)offset
|
||||||
|
tag:(long)tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads bytes until (and including) the passed "data" parameter, which acts as a separator.
|
||||||
|
*
|
||||||
|
* If the timeout value is negative, the read operation will not use a timeout.
|
||||||
|
*
|
||||||
|
* If maxLength is zero, no length restriction is enforced.
|
||||||
|
* Otherwise if maxLength bytes are read without completing the read,
|
||||||
|
* it is treated similarly to a timeout - the socket is closed with a AsyncSocketReadMaxedOutError.
|
||||||
|
* The read will complete successfully if exactly maxLength bytes are read and the given data is found at the end.
|
||||||
|
*
|
||||||
|
* If you pass nil or zero-length data as the "data" parameter,
|
||||||
|
* the method will do nothing, and the delegate will not be called.
|
||||||
|
* If you pass a maxLength parameter that is less than the length of the data parameter,
|
||||||
|
* the method will do nothing, and the delegate will not be called.
|
||||||
|
*
|
||||||
|
* To read a line from the socket, use the line separator (e.g. CRLF for HTTP, see below) as the "data" parameter.
|
||||||
|
* Note that this method is not character-set aware, so if a separator can occur naturally as part of the encoding for
|
||||||
|
* a character, the read will prematurely end.
|
||||||
|
**/
|
||||||
|
- (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout maxLength:(NSUInteger)length tag:(long)tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads bytes until (and including) the passed "data" parameter, which acts as a separator.
|
||||||
|
* The bytes will be appended to the given byte buffer starting at the given offset.
|
||||||
|
* The given buffer will automatically be increased in size if needed.
|
||||||
|
* A maximum of length bytes will be read.
|
||||||
|
*
|
||||||
|
* If the timeout value is negative, the read operation will not use a timeout.
|
||||||
|
* If the buffer if nil, a buffer will automatically be created for you.
|
||||||
|
*
|
||||||
|
* If maxLength is zero, no length restriction is enforced.
|
||||||
|
* Otherwise if maxLength bytes are read without completing the read,
|
||||||
|
* it is treated similarly to a timeout - the socket is closed with a AsyncSocketReadMaxedOutError.
|
||||||
|
* The read will complete successfully if exactly maxLength bytes are read and the given data is found at the end.
|
||||||
|
*
|
||||||
|
* If you pass a maxLength parameter that is less than the length of the data parameter,
|
||||||
|
* the method will do nothing, and the delegate will not be called.
|
||||||
|
* If the bufferOffset is greater than the length of the given buffer,
|
||||||
|
* the method will do nothing, and the delegate will not be called.
|
||||||
|
*
|
||||||
|
* If you pass a buffer, you must not alter it in any way while AsyncSocket is using it.
|
||||||
|
* After completion, the data returned in onSocket:didReadData:withTag: will be a subset of the given buffer.
|
||||||
|
* That is, it will reference the bytes that were appended to the given buffer.
|
||||||
|
*
|
||||||
|
* To read a line from the socket, use the line separator (e.g. CRLF for HTTP, see below) as the "data" parameter.
|
||||||
|
* Note that this method is not character-set aware, so if a separator can occur naturally as part of the encoding for
|
||||||
|
* a character, the read will prematurely end.
|
||||||
|
**/
|
||||||
|
- (void)readDataToData:(NSData *)data
|
||||||
|
withTimeout:(NSTimeInterval)timeout
|
||||||
|
buffer:(NSMutableData *)buffer
|
||||||
|
bufferOffset:(NSUInteger)offset
|
||||||
|
maxLength:(NSUInteger)length
|
||||||
|
tag:(long)tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes data to the socket, and calls the delegate when finished.
|
||||||
|
*
|
||||||
|
* If you pass in nil or zero-length data, this method does nothing and the delegate will not be called.
|
||||||
|
* If the timeout value is negative, the write operation will not use a timeout.
|
||||||
|
**/
|
||||||
|
- (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns progress of current read or write, from 0.0 to 1.0, or NaN if no read/write (use isnan() to check).
|
||||||
|
* "tag", "done" and "total" will be filled in if they aren't NULL.
|
||||||
|
**/
|
||||||
|
- (float)progressOfReadReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
|
||||||
|
- (float)progressOfWriteReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Secures the connection using SSL/TLS.
|
||||||
|
*
|
||||||
|
* This method may be called at any time, and the TLS handshake will occur after all pending reads and writes
|
||||||
|
* are finished. This allows one the option of sending a protocol dependent StartTLS message, and queuing
|
||||||
|
* the upgrade to TLS at the same time, without having to wait for the write to finish.
|
||||||
|
* Any reads or writes scheduled after this method is called will occur over the secured connection.
|
||||||
|
*
|
||||||
|
* The possible keys and values for the TLS settings are well documented.
|
||||||
|
* Some possible keys are:
|
||||||
|
* - kCFStreamSSLLevel
|
||||||
|
* - kCFStreamSSLAllowsExpiredCertificates
|
||||||
|
* - kCFStreamSSLAllowsExpiredRoots
|
||||||
|
* - kCFStreamSSLAllowsAnyRoot
|
||||||
|
* - kCFStreamSSLValidatesCertificateChain
|
||||||
|
* - kCFStreamSSLPeerName
|
||||||
|
* - kCFStreamSSLCertificates
|
||||||
|
* - kCFStreamSSLIsServer
|
||||||
|
*
|
||||||
|
* Please refer to Apple's documentation for associated values, as well as other possible keys.
|
||||||
|
*
|
||||||
|
* If you pass in nil or an empty dictionary, the default settings will be used.
|
||||||
|
*
|
||||||
|
* The default settings will check to make sure the remote party's certificate is signed by a
|
||||||
|
* trusted 3rd party certificate agency (e.g. verisign) and that the certificate is not expired.
|
||||||
|
* However it will not verify the name on the certificate unless you
|
||||||
|
* give it a name to verify against via the kCFStreamSSLPeerName key.
|
||||||
|
* The security implications of this are important to understand.
|
||||||
|
* Imagine you are attempting to create a secure connection to MySecureServer.com,
|
||||||
|
* but your socket gets directed to MaliciousServer.com because of a hacked DNS server.
|
||||||
|
* If you simply use the default settings, and MaliciousServer.com has a valid certificate,
|
||||||
|
* the default settings will not detect any problems since the certificate is valid.
|
||||||
|
* To properly secure your connection in this particular scenario you
|
||||||
|
* should set the kCFStreamSSLPeerName property to "MySecureServer.com".
|
||||||
|
* If you do not know the peer name of the remote host in advance (for example, you're not sure
|
||||||
|
* if it will be "domain.com" or "www.domain.com"), then you can use the default settings to validate the
|
||||||
|
* certificate, and then use the X509Certificate class to verify the issuer after the socket has been secured.
|
||||||
|
* The X509Certificate class is part of the CocoaAsyncSocket open source project.
|
||||||
|
**/
|
||||||
|
- (void)startTLS:(NSDictionary *)tlsSettings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For handling readDataToData requests, data is necessarily read from the socket in small increments.
|
||||||
|
* The performance can be much improved by allowing AsyncSocket to read larger chunks at a time and
|
||||||
|
* store any overflow in a small internal buffer.
|
||||||
|
* This is termed pre-buffering, as some data may be read for you before you ask for it.
|
||||||
|
* If you use readDataToData a lot, enabling pre-buffering will result in better performance, especially on the iPhone.
|
||||||
|
*
|
||||||
|
* The default pre-buffering state is controlled by the DEFAULT_PREBUFFERING definition.
|
||||||
|
* It is highly recommended one leave this set to YES.
|
||||||
|
*
|
||||||
|
* This method exists in case pre-buffering needs to be disabled by default for some unforeseen reason.
|
||||||
|
* In that case, this method exists to allow one to easily enable pre-buffering when ready.
|
||||||
|
**/
|
||||||
|
- (void)enablePreBuffering;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When you create an AsyncSocket, it is added to the runloop of the current thread.
|
||||||
|
* So for manually created sockets, it is easiest to simply create the socket on the thread you intend to use it.
|
||||||
|
*
|
||||||
|
* If a new socket is accepted, the delegate method onSocket:wantsRunLoopForNewSocket: is called to
|
||||||
|
* allow you to place the socket on a separate thread. This works best in conjunction with a thread pool design.
|
||||||
|
*
|
||||||
|
* If, however, you need to move the socket to a separate thread at a later time, this
|
||||||
|
* method may be used to accomplish the task.
|
||||||
|
*
|
||||||
|
* This method must be called from the thread/runloop the socket is currently running on.
|
||||||
|
*
|
||||||
|
* Note: After calling this method, all further method calls to this object should be done from the given runloop.
|
||||||
|
* Also, all delegate calls will be sent on the given runloop.
|
||||||
|
**/
|
||||||
|
- (BOOL)moveToRunLoop:(NSRunLoop *)runLoop;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows you to configure which run loop modes the socket uses.
|
||||||
|
* The default set of run loop modes is NSDefaultRunLoopMode.
|
||||||
|
*
|
||||||
|
* If you'd like your socket to continue operation during other modes, you may want to add modes such as
|
||||||
|
* NSModalPanelRunLoopMode or NSEventTrackingRunLoopMode. Or you may simply want to use NSRunLoopCommonModes.
|
||||||
|
*
|
||||||
|
* Accepted sockets will automatically inherit the same run loop modes as the listening socket.
|
||||||
|
*
|
||||||
|
* Note: NSRunLoopCommonModes is defined in 10.5. For previous versions one can use kCFRunLoopCommonModes.
|
||||||
|
**/
|
||||||
|
- (BOOL)setRunLoopModes:(NSArray *)runLoopModes;
|
||||||
|
- (BOOL)addRunLoopMode:(NSString *)runLoopMode;
|
||||||
|
- (BOOL)removeRunLoopMode:(NSString *)runLoopMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current run loop modes the AsyncSocket instance is operating in.
|
||||||
|
* The default set of run loop modes is NSDefaultRunLoopMode.
|
||||||
|
**/
|
||||||
|
- (NSArray *)runLoopModes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In the event of an error, this method may be called during onSocket:willDisconnectWithError: to read
|
||||||
|
* any data that's left on the socket.
|
||||||
|
**/
|
||||||
|
- (NSData *)unreadData;
|
||||||
|
|
||||||
|
/* A few common line separators, for use with the readDataToData:... methods. */
|
||||||
|
+ (NSData *)CRLFData; // 0x0D0A
|
||||||
|
+ (NSData *)CRData; // 0x0D
|
||||||
|
+ (NSData *)LFData; // 0x0A
|
||||||
|
+ (NSData *)ZeroData; // 0x00
|
||||||
|
|
||||||
|
@end
|
@ -0,0 +1,368 @@
|
|||||||
|
//
|
||||||
|
// AsyncUdpSocket.h
|
||||||
|
//
|
||||||
|
// This class is in the public domain.
|
||||||
|
// Originally created by Robbie Hanson on Wed Oct 01 2008.
|
||||||
|
// Updated and maintained by Deusty Designs and the Mac development community.
|
||||||
|
//
|
||||||
|
// http://code.google.com/p/cocoaasyncsocket/
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
@class AsyncSendPacket;
|
||||||
|
@class AsyncReceivePacket;
|
||||||
|
|
||||||
|
extern NSString *const AsyncUdpSocketException;
|
||||||
|
extern NSString *const AsyncUdpSocketErrorDomain;
|
||||||
|
|
||||||
|
typedef NS_ENUM(NSInteger, AsyncUdpSocketError) {
|
||||||
|
AsyncUdpSocketCFSocketError = kCFSocketError, // From CFSocketError enum
|
||||||
|
AsyncUdpSocketNoError = 0, // Never used
|
||||||
|
AsyncUdpSocketBadParameter, // Used if given a bad parameter (such as an improper address)
|
||||||
|
AsyncUdpSocketIPv4Unavailable, // Used if you bind/connect using IPv6 only
|
||||||
|
AsyncUdpSocketIPv6Unavailable, // Used if you bind/connect using IPv4 only (or iPhone)
|
||||||
|
AsyncUdpSocketSendTimeoutError,
|
||||||
|
AsyncUdpSocketReceiveTimeoutError
|
||||||
|
};
|
||||||
|
|
||||||
|
@interface AsyncUdpSocket : NSObject
|
||||||
|
{
|
||||||
|
CFSocketRef theSocket4; // IPv4 socket
|
||||||
|
CFSocketRef theSocket6; // IPv6 socket
|
||||||
|
|
||||||
|
CFRunLoopSourceRef theSource4; // For theSocket4
|
||||||
|
CFRunLoopSourceRef theSource6; // For theSocket6
|
||||||
|
CFRunLoopRef theRunLoop;
|
||||||
|
CFSocketContext theContext;
|
||||||
|
NSArray *theRunLoopModes;
|
||||||
|
|
||||||
|
NSMutableArray *theSendQueue;
|
||||||
|
AsyncSendPacket *theCurrentSend;
|
||||||
|
NSTimer *theSendTimer;
|
||||||
|
|
||||||
|
NSMutableArray *theReceiveQueue;
|
||||||
|
AsyncReceivePacket *theCurrentReceive;
|
||||||
|
NSTimer *theReceiveTimer;
|
||||||
|
|
||||||
|
id theDelegate;
|
||||||
|
UInt16 theFlags;
|
||||||
|
|
||||||
|
long theUserData;
|
||||||
|
|
||||||
|
NSString *cachedLocalHost;
|
||||||
|
UInt16 cachedLocalPort;
|
||||||
|
|
||||||
|
NSString *cachedConnectedHost;
|
||||||
|
UInt16 cachedConnectedPort;
|
||||||
|
|
||||||
|
UInt32 maxReceiveBufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new instances of AsyncUdpSocket.
|
||||||
|
**/
|
||||||
|
- (id)init;
|
||||||
|
- (id)initWithDelegate:(id)delegate;
|
||||||
|
- (id)initWithDelegate:(id)delegate userData:(long)userData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new instances of AsyncUdpSocket that support only IPv4 or IPv6.
|
||||||
|
* The other init methods will support both, unless specifically binded or connected to one protocol.
|
||||||
|
* If you know you'll only be using one protocol, these init methods may be a bit more efficient.
|
||||||
|
**/
|
||||||
|
- (id)initIPv4;
|
||||||
|
- (id)initIPv6;
|
||||||
|
|
||||||
|
- (id)delegate;
|
||||||
|
- (void)setDelegate:(id)delegate;
|
||||||
|
|
||||||
|
- (long)userData;
|
||||||
|
- (void)setUserData:(long)userData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the local address info for the socket.
|
||||||
|
*
|
||||||
|
* Note: Address info may not be available until after the socket has been bind'ed,
|
||||||
|
* or until after data has been sent.
|
||||||
|
**/
|
||||||
|
- (NSString *)localHost;
|
||||||
|
- (UInt16)localPort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the remote address info for the socket.
|
||||||
|
*
|
||||||
|
* Note: Since UDP is connectionless by design, connected address info
|
||||||
|
* will not be available unless the socket is explicitly connected to a remote host/port
|
||||||
|
**/
|
||||||
|
- (NSString *)connectedHost;
|
||||||
|
- (UInt16)connectedPort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not this socket has been connected to a single host.
|
||||||
|
* By design, UDP is a connectionless protocol, and connecting is not needed.
|
||||||
|
* If connected, the socket will only be able to send/receive data to/from the connected host.
|
||||||
|
**/
|
||||||
|
- (BOOL)isConnected;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not this socket has been closed.
|
||||||
|
* The only way a socket can be closed is if you explicitly call one of the close methods.
|
||||||
|
**/
|
||||||
|
- (BOOL)isClosed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not this socket supports IPv4.
|
||||||
|
* By default this will be true, unless the socket is specifically initialized as IPv6 only,
|
||||||
|
* or is binded or connected to an IPv6 address.
|
||||||
|
**/
|
||||||
|
- (BOOL)isIPv4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not this socket supports IPv6.
|
||||||
|
* By default this will be true, unless the socket is specifically initialized as IPv4 only,
|
||||||
|
* or is binded or connected to an IPv4 address.
|
||||||
|
*
|
||||||
|
* This method will also return false on platforms that do not support IPv6.
|
||||||
|
* Note: The iPhone does not currently support IPv6.
|
||||||
|
**/
|
||||||
|
- (BOOL)isIPv6;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the mtu of the socket.
|
||||||
|
* If unknown, returns zero.
|
||||||
|
*
|
||||||
|
* Sending data larger than this may result in an error.
|
||||||
|
* This is an advanced topic, and one should understand the wide range of mtu's on networks and the internet.
|
||||||
|
* Therefore this method is only for reference and may be of little use in many situations.
|
||||||
|
**/
|
||||||
|
- (unsigned int)maximumTransmissionUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds the UDP socket to the given port and optional address.
|
||||||
|
* Binding should be done for server sockets that receive data prior to sending it.
|
||||||
|
* Client sockets can skip binding,
|
||||||
|
* as the OS will automatically assign the socket an available port when it starts sending data.
|
||||||
|
*
|
||||||
|
* You cannot bind a socket after its been connected.
|
||||||
|
* You can only bind a socket once.
|
||||||
|
* You can still connect a socket (if desired) after binding.
|
||||||
|
*
|
||||||
|
* On success, returns YES.
|
||||||
|
* Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass nil for errPtr.
|
||||||
|
**/
|
||||||
|
- (BOOL)bindToPort:(UInt16)port error:(NSError **)errPtr;
|
||||||
|
- (BOOL)bindToAddress:(NSString *)localAddr port:(UInt16)port error:(NSError **)errPtr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects the UDP socket to the given host and port.
|
||||||
|
* By design, UDP is a connectionless protocol, and connecting is not needed.
|
||||||
|
*
|
||||||
|
* Choosing to connect to a specific host/port has the following effect:
|
||||||
|
* - You will only be able to send data to the connected host/port.
|
||||||
|
* - You will only be able to receive data from the connected host/port.
|
||||||
|
* - You will receive ICMP messages that come from the connected host/port, such as "connection refused".
|
||||||
|
*
|
||||||
|
* Connecting a UDP socket does not result in any communication on the socket.
|
||||||
|
* It simply changes the internal state of the socket.
|
||||||
|
*
|
||||||
|
* You cannot bind a socket after its been connected.
|
||||||
|
* You can only connect a socket once.
|
||||||
|
*
|
||||||
|
* On success, returns YES.
|
||||||
|
* Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass nil for errPtr.
|
||||||
|
**/
|
||||||
|
- (BOOL)connectToHost:(NSString *)host onPort:(UInt16)port error:(NSError **)errPtr;
|
||||||
|
- (BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError **)errPtr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Join multicast group
|
||||||
|
*
|
||||||
|
* Group should be an IP address (eg @"225.228.0.1")
|
||||||
|
**/
|
||||||
|
- (BOOL)joinMulticastGroup:(NSString *)group error:(NSError **)errPtr;
|
||||||
|
- (BOOL)joinMulticastGroup:(NSString *)group withAddress:(NSString *)interface error:(NSError **)errPtr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default, the underlying socket in the OS will not allow you to send broadcast messages.
|
||||||
|
* In order to send broadcast messages, you need to enable this functionality in the socket.
|
||||||
|
*
|
||||||
|
* A broadcast is a UDP message to addresses like "192.168.255.255" or "255.255.255.255" that is
|
||||||
|
* delivered to every host on the network.
|
||||||
|
* The reason this is generally disabled by default is to prevent
|
||||||
|
* accidental broadcast messages from flooding the network.
|
||||||
|
**/
|
||||||
|
- (BOOL)enableBroadcast:(BOOL)flag error:(NSError **)errPtr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asynchronously sends the given data, with the given timeout and tag.
|
||||||
|
*
|
||||||
|
* This method may only be used with a connected socket.
|
||||||
|
*
|
||||||
|
* If data is nil or zero-length, this method does nothing and immediately returns NO.
|
||||||
|
* If the socket is not connected, this method does nothing and immediately returns NO.
|
||||||
|
**/
|
||||||
|
- (BOOL)sendData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asynchronously sends the given data, with the given timeout and tag, to the given host and port.
|
||||||
|
*
|
||||||
|
* This method cannot be used with a connected socket.
|
||||||
|
*
|
||||||
|
* If data is nil or zero-length, this method does nothing and immediately returns NO.
|
||||||
|
* If the socket is connected, this method does nothing and immediately returns NO.
|
||||||
|
* If unable to resolve host to a valid IPv4 or IPv6 address, this method returns NO.
|
||||||
|
**/
|
||||||
|
- (BOOL)sendData:(NSData *)data toHost:(NSString *)host port:(UInt16)port withTimeout:(NSTimeInterval)timeout tag:(long)tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asynchronously sends the given data, with the given timeout and tag, to the given address.
|
||||||
|
*
|
||||||
|
* This method cannot be used with a connected socket.
|
||||||
|
*
|
||||||
|
* If data is nil or zero-length, this method does nothing and immediately returns NO.
|
||||||
|
* If the socket is connected, this method does nothing and immediately returns NO.
|
||||||
|
**/
|
||||||
|
- (BOOL)sendData:(NSData *)data toAddress:(NSData *)remoteAddr withTimeout:(NSTimeInterval)timeout tag:(long)tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asynchronously receives a single datagram packet.
|
||||||
|
*
|
||||||
|
* If the receive succeeds, the onUdpSocket:didReceiveData:fromHost:port:tag delegate method will be called.
|
||||||
|
* Otherwise, a timeout will occur, and the onUdpSocket:didNotReceiveDataWithTag: delegate method will be called.
|
||||||
|
**/
|
||||||
|
- (void)receiveWithTimeout:(NSTimeInterval)timeout tag:(long)tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the socket immediately. Any pending send or receive operations are dropped.
|
||||||
|
**/
|
||||||
|
- (void)close;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes after all pending send operations have completed.
|
||||||
|
* After calling this, the sendData: and receive: methods will do nothing.
|
||||||
|
* In other words, you won't be able to add any more send or receive operations to the queue.
|
||||||
|
* The socket will close even if there are still pending receive operations.
|
||||||
|
**/
|
||||||
|
- (void)closeAfterSending;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes after all pending receive operations have completed.
|
||||||
|
* After calling this, the sendData: and receive: methods will do nothing.
|
||||||
|
* In other words, you won't be able to add any more send or receive operations to the queue.
|
||||||
|
* The socket will close even if there are still pending send operations.
|
||||||
|
**/
|
||||||
|
- (void)closeAfterReceiving;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes after all pending send and receive operations have completed.
|
||||||
|
* After calling this, the sendData: and receive: methods will do nothing.
|
||||||
|
* In other words, you won't be able to add any more send or receive operations to the queue.
|
||||||
|
**/
|
||||||
|
- (void)closeAfterSendingAndReceiving;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets/Sets the maximum size of the buffer that will be allocated for receive operations.
|
||||||
|
* The default size is 9216 bytes.
|
||||||
|
*
|
||||||
|
* The theoretical maximum size of any IPv4 UDP packet is UINT16_MAX = 65535.
|
||||||
|
* The theoretical maximum size of any IPv6 UDP packet is UINT32_MAX = 4294967295.
|
||||||
|
*
|
||||||
|
* In practice, however, the size of UDP packets will be much smaller.
|
||||||
|
* Indeed most protocols will send and receive packets of only a few bytes,
|
||||||
|
* or will set a limit on the size of packets to prevent fragmentation in the IP layer.
|
||||||
|
*
|
||||||
|
* If you set the buffer size too small, the sockets API in the OS will silently discard
|
||||||
|
* any extra data, and you will not be notified of the error.
|
||||||
|
**/
|
||||||
|
- (UInt32)maxReceiveBufferSize;
|
||||||
|
- (void)setMaxReceiveBufferSize:(UInt32)max;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When you create an AsyncUdpSocket, it is added to the runloop of the current thread.
|
||||||
|
* So it is easiest to simply create the socket on the thread you intend to use it.
|
||||||
|
*
|
||||||
|
* If, however, you need to move the socket to a separate thread at a later time, this
|
||||||
|
* method may be used to accomplish the task.
|
||||||
|
*
|
||||||
|
* This method must be called from the thread/runloop the socket is currently running on.
|
||||||
|
*
|
||||||
|
* Note: After calling this method, all further method calls to this object should be done from the given runloop.
|
||||||
|
* Also, all delegate calls will be sent on the given runloop.
|
||||||
|
**/
|
||||||
|
- (BOOL)moveToRunLoop:(NSRunLoop *)runLoop;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows you to configure which run loop modes the socket uses.
|
||||||
|
* The default set of run loop modes is NSDefaultRunLoopMode.
|
||||||
|
*
|
||||||
|
* If you'd like your socket to continue operation during other modes, you may want to add modes such as
|
||||||
|
* NSModalPanelRunLoopMode or NSEventTrackingRunLoopMode. Or you may simply want to use NSRunLoopCommonModes.
|
||||||
|
*
|
||||||
|
* Note: NSRunLoopCommonModes is defined in 10.5. For previous versions one can use kCFRunLoopCommonModes.
|
||||||
|
**/
|
||||||
|
- (BOOL)setRunLoopModes:(NSArray *)runLoopModes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current run loop modes the AsyncSocket instance is operating in.
|
||||||
|
* The default set of run loop modes is NSDefaultRunLoopMode.
|
||||||
|
**/
|
||||||
|
- (NSArray *)runLoopModes;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#pragma mark -
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@protocol AsyncUdpSocketDelegate
|
||||||
|
@optional
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the datagram with the given tag has been sent.
|
||||||
|
**/
|
||||||
|
- (void)onUdpSocket:(AsyncUdpSocket *)sock didSendDataWithTag:(long)tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called if an error occurs while trying to send a datagram.
|
||||||
|
* This could be due to a timeout, or something more serious such as the data being too large to fit in a sigle packet.
|
||||||
|
**/
|
||||||
|
- (void)onUdpSocket:(AsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError *)error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the socket has received the requested datagram.
|
||||||
|
*
|
||||||
|
* Due to the nature of UDP, you may occasionally receive undesired packets.
|
||||||
|
* These may be rogue UDP packets from unknown hosts,
|
||||||
|
* or they may be delayed packets arriving after retransmissions have already occurred.
|
||||||
|
* It's important these packets are properly ignored, while not interfering with the flow of your implementation.
|
||||||
|
* As an aid, this delegate method has a boolean return value.
|
||||||
|
* If you ever need to ignore a received packet, simply return NO,
|
||||||
|
* and AsyncUdpSocket will continue as if the packet never arrived.
|
||||||
|
* That is, the original receive request will still be queued, and will still timeout as usual if a timeout was set.
|
||||||
|
* For example, say you requested to receive data, and you set a timeout of 500 milliseconds, using a tag of 15.
|
||||||
|
* If rogue data arrives after 250 milliseconds, this delegate method would be invoked, and you could simply return NO.
|
||||||
|
* If the expected data then arrives within the next 250 milliseconds,
|
||||||
|
* this delegate method will be invoked, with a tag of 15, just as if the rogue data never appeared.
|
||||||
|
*
|
||||||
|
* Under normal circumstances, you simply return YES from this method.
|
||||||
|
**/
|
||||||
|
- (BOOL)onUdpSocket:(AsyncUdpSocket *)sock
|
||||||
|
didReceiveData:(NSData *)data
|
||||||
|
withTag:(long)tag
|
||||||
|
fromHost:(NSString *)host
|
||||||
|
port:(UInt16)port;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called if an error occurs while trying to receive a requested datagram.
|
||||||
|
* This is generally due to a timeout, but could potentially be something else if some kind of OS error occurred.
|
||||||
|
**/
|
||||||
|
- (void)onUdpSocket:(AsyncUdpSocket *)sock didNotReceiveDataWithTag:(long)tag dueToError:(NSError *)error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the socket is closed.
|
||||||
|
* A socket is only closed if you explicitly call one of the close methods.
|
||||||
|
**/
|
||||||
|
- (void)onUdpSocketDidClose:(AsyncUdpSocket *)sock;
|
||||||
|
|
||||||
|
@end
|
@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// CocoaAsyncSocket.h
|
||||||
|
// CocoaAsyncSocket
|
||||||
|
//
|
||||||
|
// Created by Derek Clarkson on 10/08/2015.
|
||||||
|
// Copyright © 2015 Robbie Hanson. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
@import Foundation;
|
||||||
|
|
||||||
|
//! Project version number for CocoaAsyncSocket.
|
||||||
|
FOUNDATION_EXPORT double cocoaAsyncSocketVersionNumber;
|
||||||
|
|
||||||
|
//! Project version string for CocoaAsyncSocket.
|
||||||
|
FOUNDATION_EXPORT const unsigned char cocoaAsyncSocketVersionString[];
|
||||||
|
|
||||||
|
#import <CocoaAsyncSocket/AsyncSocket.h>
|
||||||
|
#import <CocoaAsyncSocket/AsyncUdpSocket.h>
|
||||||
|
#import <CocoaAsyncSocket/GCDAsyncSocket.h>
|
||||||
|
#import <CocoaAsyncSocket/GCDAsyncUdpSocket.h>
|
1177
ios/Framework/CocoaAsyncSocket.framework/Headers/GCDAsyncSocket.h
Normal file
1177
ios/Framework/CocoaAsyncSocket.framework/Headers/GCDAsyncSocket.h
Normal file
File diff suppressed because it is too large
Load Diff
1007
ios/Framework/CocoaAsyncSocket.framework/Headers/GCDAsyncUdpSocket.h
Normal file
1007
ios/Framework/CocoaAsyncSocket.framework/Headers/GCDAsyncUdpSocket.h
Normal file
File diff suppressed because it is too large
Load Diff
BIN
ios/Framework/CocoaAsyncSocket.framework/Info.plist
Normal file
BIN
ios/Framework/CocoaAsyncSocket.framework/Info.plist
Normal file
Binary file not shown.
@ -0,0 +1,6 @@
|
|||||||
|
framework module CocoaAsyncSocket {
|
||||||
|
umbrella header "CocoaAsyncSocket.h"
|
||||||
|
|
||||||
|
export *
|
||||||
|
module * { export * }
|
||||||
|
}
|
@ -0,0 +1,201 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>files</key>
|
||||||
|
<dict>
|
||||||
|
<key>Headers/AsyncSocket.h</key>
|
||||||
|
<data>
|
||||||
|
GyStCmhuxAWLghA+fHLwPiSbVNI=
|
||||||
|
</data>
|
||||||
|
<key>Headers/AsyncUdpSocket.h</key>
|
||||||
|
<data>
|
||||||
|
oqLPl3ROAyiOqTaqhuupNjuxVU0=
|
||||||
|
</data>
|
||||||
|
<key>Headers/CocoaAsyncSocket.h</key>
|
||||||
|
<data>
|
||||||
|
fwx/DHzHzUQhtlfC9ffKAK+SFx0=
|
||||||
|
</data>
|
||||||
|
<key>Headers/GCDAsyncSocket.h</key>
|
||||||
|
<data>
|
||||||
|
/7aHrd4SpiKhqk1H7YRnTBSmJow=
|
||||||
|
</data>
|
||||||
|
<key>Headers/GCDAsyncUdpSocket.h</key>
|
||||||
|
<data>
|
||||||
|
LH5V3wgNYRH1dy/fNu8r4lu8puI=
|
||||||
|
</data>
|
||||||
|
<key>Info.plist</key>
|
||||||
|
<data>
|
||||||
|
hIIk3iGpMXJkFPisCMWGNsBtuQI=
|
||||||
|
</data>
|
||||||
|
<key>Modules/module.modulemap</key>
|
||||||
|
<data>
|
||||||
|
+n94rYTWDjekX3imyh+PSyA9vgA=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>files2</key>
|
||||||
|
<dict>
|
||||||
|
<key>Headers/AsyncSocket.h</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash</key>
|
||||||
|
<data>
|
||||||
|
GyStCmhuxAWLghA+fHLwPiSbVNI=
|
||||||
|
</data>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
FK+dN4jyAlPVkpV5Ai//YboXm9aUxPv3x3Q3viDjqTU=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>Headers/AsyncUdpSocket.h</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash</key>
|
||||||
|
<data>
|
||||||
|
oqLPl3ROAyiOqTaqhuupNjuxVU0=
|
||||||
|
</data>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
aTSbXrHSbcwPrz3/NoP6Q+jWZEwou6OSHQh/8WRkf/0=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>Headers/CocoaAsyncSocket.h</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash</key>
|
||||||
|
<data>
|
||||||
|
fwx/DHzHzUQhtlfC9ffKAK+SFx0=
|
||||||
|
</data>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
OeCNZd4h1R70nH11jcrFn8m1hnTuvTAHjDhMuhI/3Ao=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>Headers/GCDAsyncSocket.h</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash</key>
|
||||||
|
<data>
|
||||||
|
/7aHrd4SpiKhqk1H7YRnTBSmJow=
|
||||||
|
</data>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
bOafNUOs6luKovAV0sGzRLmHYf/vKZPF/Wg0IJD1zwQ=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>Headers/GCDAsyncUdpSocket.h</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash</key>
|
||||||
|
<data>
|
||||||
|
LH5V3wgNYRH1dy/fNu8r4lu8puI=
|
||||||
|
</data>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
CAMdz3VphGMLZyKBHhxLfGK4d70mHUiuHsG45jRPi+0=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>Modules/module.modulemap</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash</key>
|
||||||
|
<data>
|
||||||
|
+n94rYTWDjekX3imyh+PSyA9vgA=
|
||||||
|
</data>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
RoVn8xMeEnU3Izg0DtYjYL/krI8V7qw0sa7Ggf+08Rs=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<key>rules</key>
|
||||||
|
<dict>
|
||||||
|
<key>^</key>
|
||||||
|
<true/>
|
||||||
|
<key>^.*\.lproj/</key>
|
||||||
|
<dict>
|
||||||
|
<key>optional</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1000</real>
|
||||||
|
</dict>
|
||||||
|
<key>^.*\.lproj/locversion.plist$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1100</real>
|
||||||
|
</dict>
|
||||||
|
<key>^version.plist$</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>rules2</key>
|
||||||
|
<dict>
|
||||||
|
<key>.*\.dSYM($|/)</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>11</real>
|
||||||
|
</dict>
|
||||||
|
<key>^</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
<key>^(.*/)?\.DS_Store$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>2000</real>
|
||||||
|
</dict>
|
||||||
|
<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
|
||||||
|
<dict>
|
||||||
|
<key>nested</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>10</real>
|
||||||
|
</dict>
|
||||||
|
<key>^.*</key>
|
||||||
|
<true/>
|
||||||
|
<key>^.*\.lproj/</key>
|
||||||
|
<dict>
|
||||||
|
<key>optional</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1000</real>
|
||||||
|
</dict>
|
||||||
|
<key>^.*\.lproj/locversion.plist$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1100</real>
|
||||||
|
</dict>
|
||||||
|
<key>^Info\.plist$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
<key>^PkgInfo$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
<key>^[^/]+$</key>
|
||||||
|
<dict>
|
||||||
|
<key>nested</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>10</real>
|
||||||
|
</dict>
|
||||||
|
<key>^embedded\.provisionprofile$</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
<key>^version\.plist$</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
Loading…
Reference in New Issue
Block a user