IOS Streaming Browser 1.0
An IOS streaming browser to stream the display to others or to a projector

GCDAsyncSocket Class Reference

#import <GCDAsyncSocket.h>

Collaboration diagram for GCDAsyncSocket:

Public Member Functions

(id) - init
(id) - initWithSocketQueue:
(id) - initWithDelegate:delegateQueue:
(id) - initWithDelegate:delegateQueue:socketQueue:
(id) - delegate
(void) - setDelegate:
(void) - synchronouslySetDelegate:
(dispatch_queue_t) - delegateQueue
(void) - setDelegateQueue:
(void) - synchronouslySetDelegateQueue:
(void) - getDelegate:delegateQueue:
(void) - setDelegate:delegateQueue:
(void) - synchronouslySetDelegate:delegateQueue:
(BOOL) - autoDisconnectOnClosedReadStream
(void) - setAutoDisconnectOnClosedReadStream:
(BOOL) - isIPv4Enabled
(void) - setIPv4Enabled:
(BOOL) - isIPv6Enabled
(void) - setIPv6Enabled:
(BOOL) - isIPv4PreferredOverIPv6
(void) - setPreferIPv4OverIPv6:
(id) - userData
(void) - setUserData:
(BOOL) - acceptOnPort:error:
(BOOL) - acceptOnInterface:port:error:
(BOOL) - connectToHost:onPort:error:
(BOOL) - connectToHost:onPort:withTimeout:error:
(BOOL) - connectToHost:onPort:viaInterface:withTimeout:error:
(BOOL) - connectToAddress:error:
(BOOL) - connectToAddress:withTimeout:error:
(BOOL) - connectToAddress:viaInterface:withTimeout:error:
(void) - disconnect
(void) - disconnectAfterReading
(void) - disconnectAfterWriting
(void) - disconnectAfterReadingAndWriting
(BOOL) - isDisconnected
(BOOL) - isConnected
(NSString *) - connectedHost
(UInt16) - connectedPort
(NSString *) - localHost
(UInt16) - localPort
(NSData *) - connectedAddress
(NSData *) - localAddress
(BOOL) - isIPv4
(BOOL) - isIPv6
(void) - readDataWithTimeout:tag:
(void) - readDataWithTimeout:buffer:bufferOffset:tag:
(void) - readDataWithTimeout:buffer:bufferOffset:maxLength:tag:
(void) - readDataToLength:withTimeout:tag:
(void) - readDataToLength:withTimeout:buffer:bufferOffset:tag:
(void) - readDataToData:withTimeout:tag:
(void) - readDataToData:withTimeout:buffer:bufferOffset:tag:
(void) - readDataToData:withTimeout:maxLength:tag:
(void) - readDataToData:withTimeout:buffer:bufferOffset:maxLength:tag:
(void) - writeData:withTimeout:tag:
(void) - startTLS:
(void) - performBlock:
(int) - socketFD
(int) - socket4FD
(int) - socket6FD
(SSLContextRef) - sslContext
(BOOL) - doAccept:
(void) - startConnectTimeout:
(void) - endConnectTimeout
(void) - doConnectTimeout
(void) - lookup:host:port:
(void) - lookup:didSucceedWithAddress4:address6:
(void) - lookup:didFail:
(BOOL) - connectWithAddress4:address6:error:
(void) - didConnect:
(void) - didNotConnect:error:
(void) - closeWithError:
(void) - close
(void) - maybeClose
(NSError *) - badConfigError:
(NSError *) - badParamError:
(NSError *) - gaiError:
(NSError *) - errnoError
(NSError *) - errnoErrorWithReason:
(NSError *) - connectTimeoutError
(NSError *) - otherError:
(NSString *) - connectedHost4
(NSString *) - connectedHost6
(UInt16) - connectedPort4
(UInt16) - connectedPort6
(NSString *) - localHost4
(NSString *) - localHost6
(UInt16) - localPort4
(UInt16) - localPort6
(NSString *) - connectedHostFromSocket4:
(NSString *) - connectedHostFromSocket6:
(UInt16) - connectedPortFromSocket4:
(UInt16) - connectedPortFromSocket6:
(NSString *) - localHostFromSocket4:
(NSString *) - localHostFromSocket6:
(UInt16) - localPortFromSocket4:
(UInt16) - localPortFromSocket6:
(void) - getInterfaceAddress4:address6:fromDescription:port:
(void) - setupReadAndWriteSourcesForNewlyConnectedSocket:
(void) - suspendReadSource
(void) - resumeReadSource
(void) - suspendWriteSource
(void) - resumeWriteSource
(void) - maybeDequeueRead
(void) - doReadData
(void) - doReadEOF
(void) - completeCurrentRead
(void) - endCurrentRead
(void) - setupReadTimerWithTimeout:
(void) - doReadTimeout
(void) - doReadTimeoutWithExtension:
(void) - maybeDequeueWrite
(void) - doWriteData
(void) - completeCurrentWrite
(void) - endCurrentWrite
(void) - setupWriteTimerWithTimeout:
(void) - doWriteTimeout
(void) - doWriteTimeoutWithExtension:
(void) - maybeStartTLS
(void) - continueSSLHandshake

Static Public Member Functions

(NSString *) + hostFromAddress:
(UInt16) + portFromAddress:
(BOOL) + getHost:port:fromAddress:
(NSData *) + CRLFData
(NSData *) + CRData
(NSData *) + LFData
(NSData *) + ZeroData
(NSString *) + hostFromAddress4:
(NSString *) + hostFromAddress6:
(UInt16) + portFromAddress4:
(UInt16) + portFromAddress6:

Protected Attributes

UInt16 flags
UInt16 config
id delegate
dispatch_queue_t delegateQueue
int socket4FD
int socket6FD
int connectIndex
NSDataconnectInterface4
NSDataconnectInterface6
dispatch_queue_t socketQueue
dispatch_source_t accept4Source
dispatch_source_t accept6Source
dispatch_source_t connectTimer
dispatch_source_t readSource
dispatch_source_t writeSource
dispatch_source_t readTimer
dispatch_source_t writeTimer
NSMutableArray * readQueue
NSMutableArray * writeQueue
GCDAsyncReadPacketcurrentRead
GCDAsyncWritePacketcurrentWrite
unsigned long socketFDBytesAvailable
NSMutableData * partialReadBuffer
SSLContextRef sslContext
NSMutableData * sslReadBuffer
size_t sslWriteCachedLength
id userData

Detailed Description

Definition at line 51 of file GCDAsyncSocket.h.


Member Function Documentation

- (BOOL) acceptOnInterface: (NSString *)  interface
port: (UInt16)  port
error: (NSError **)  errPtr 

This method is the same as acceptOnPort:error: with the additional option of specifying which interface to listen on.

For example, you could specify that the socket should only accept connections over ethernet, and not other interfaces such as wifi.

The interface may be specified by name (e.g. "en1" or "lo0") or by IP address (e.g. "192.168.4.34"). You may also use the special strings "localhost" or "loopback" to specify that the socket only accept connections from the local machine.

You can see the list of interfaces via the command line utility "ifconfig", or programmatically via the getifaddrs() function.

To accept connections on any interface pass nil, or simply use the acceptOnPort:error: method.

Whether accept connection on interface and port param NSString param UInt16 returns BOOL

Definition at line 2250 of file GCDAsyncSocket.m.

                         :(NSString *)interface port:(UInt16)port error:(NSError **)errPtr
{
        LogTrace();
        
    // Gets the result from the block
        __block BOOL result = YES;
        __block NSError *err = nil;
        
        // CreateSocket Block
        // This block will be invoked within the dispatch block below.
        // defines a block of createSocket type with accepts int (domain) and NSData (interface address) as arguements
    
        int(^createSocket)(int, NSData*) = ^int (int domain, NSData *interfaceAddr) {
                
        // creates an endpoint for communication and returns a descriptor
                int socketFD = socket(domain, SOCK_STREAM, 0);
                
        
                if (socketFD == SOCKET_NULL)
                {
                        NSString *reason = @"Error in socket() function";
                        err = [[self errnoErrorWithReason:reason] retain];
                        
                        return SOCKET_NULL;
                }
                
        
                int status;
                
                // Set socket options
        // file control
        // F_SETFL sets the descriptor flags
        // O_NONBLOCK - Non-blocking I/O; if no data is available to a read
        // call, or if a write operation would block, the read or
        // write call returns -1 with the error EAGAIN.
                status = fcntl(socketFD, F_SETFL, O_NONBLOCK);
                if (status == -1)
                {
                        NSString *reason = @"Error enabling non-blocking IO on socket (fcntl)";
                        err = [[self errnoErrorWithReason:reason] retain];
                        
                        close(socketFD);
                        return SOCKET_NULL;
                }
        
        // If reusing sockets
                int reuseOn = 1;
        
        // Set the options on a socket
        // SO_REUSEADDR indicates that the rules used in validating
        // addresses supplied in bind(2) call should allow reuse of 
        // local addresses
                status = setsockopt(socketFD, SOL_SOCKET, SO_REUSEADDR, &reuseOn, sizeof(reuseOn));
        
        // Check if could set the socket options
                if (status == -1)
                {
                        NSString *reason = @"Error enabling address reuse (setsockopt)";
                        err = [[self errnoErrorWithReason:reason] retain];
                        
            // Close the socket
                        close(socketFD);
                        return SOCKET_NULL;
                }
                
                // Bind socket
        
        
        // bind the socket to a interface
                status = bind(socketFD, (struct sockaddr *)[interfaceAddr bytes], (socklen_t)[interfaceAddr length]);
        
        // If could not bind socket
                if (status == -1)
                {
                        NSString *reason = @"Error in bind() function";
                        err = [[self errnoErrorWithReason:reason] retain];
                        
            // Close the socket
                        close(socketFD);
                        return SOCKET_NULL;
                }
                
                // Listen on the socket
        
        // listen for connections on a socket
                status = listen(socketFD, 1024);
        
        // Check if we can listen to a connection on a socket
                if (status == -1)
                {
                        NSString *reason = @"Error in listen() function";
                        err = [[self errnoErrorWithReason:reason] retain];
                        
            // Close the socket
                        close(socketFD);
                        return SOCKET_NULL;
                }
                
                return socketFD;
        };
        
        // Create dispatch block and run on socketQueue
        
    
        dispatch_block_t block = ^{

                NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
                
                if (delegate == nil) // Must have delegate set
                {
                        result = NO;
                        
                        NSString *msg = @"Attempting to accept without a delegate. Set a delegate first.";
                        err = [[self badConfigError:msg] retain];
                        
                        [pool drain];
                        return_from_block;
                }
                
                if (delegateQueue == NULL) // Must have delegate queue set
                {
                        result = NO;
                        
                        NSString *msg = @"Attempting to accept without a delegate queue. Set a delegate queue first.";
                        err = [[self badConfigError:msg] retain];
                        
                        [pool drain];
                        return_from_block;
                }
                
        // Whether IP version 4 protocol is disabled
                BOOL isIPv4Disabled = (config & kIPv4Disabled) ? YES : NO;
        
        // Whether IP version 6 protocol is disabled
                BOOL isIPv6Disabled = (config & kIPv6Disabled) ? YES : NO;
                
        // If both IP version 4 and IP version 6 are disabled
                if (isIPv4Disabled && isIPv6Disabled) // Must have IPv4 or IPv6 enabled
                {
                        result = NO;
                        
                        NSString *msg = @"Both IPv4 and IPv6 have been disabled. Must enable at least one protocol first.";
                        err = [[self badConfigError:msg] retain];
                        
                        [pool drain];
                        return_from_block;
                }
                
        
                if (![self isDisconnected]) // Must be disconnected
                {
                        result = NO;
                        
                        NSString *msg = @"Attempting to accept while connected or accepting connections. Disconnect first.";
                        err = [[self badConfigError:msg] retain];
                        
                        [pool drain];
                        return_from_block;
                }
                
                // Clear queues (spurious read/write requests post disconnect)
                [readQueue removeAllObjects];
                [writeQueue removeAllObjects];
                
        
                // Resolve interface from description
                
                NSData *interface4 = nil;
                NSData *interface6 = nil;
                
        // Get the interface address from an interface description and port
                [self getInterfaceAddress4:&interface4 address6:&interface6 fromDescription:interface port:port];
                
        
                if ((interface4 == nil) && (interface6 == nil))
                {
                        result = NO;
                        
                        NSString *msg = @"Unknown interface. Specify valid interface by name (e.g. \"en1\") or IP address.";
                        err = [[self badParamError:msg] retain];
                        
                        [pool drain];
                        return_from_block;
                }
                
                if (isIPv4Disabled && (interface6 == nil))
                {
                        result = NO;
                        
                        NSString *msg = @"IPv4 has been disabled and specified interface doesn't support IPv6.";
                        err = [[self badParamError:msg] retain];
                        
                        [pool drain];
                        return_from_block;
                }
                
                if (isIPv6Disabled && (interface4 == nil))
                {
                        result = NO;
                        
                        NSString *msg = @"IPv6 has been disabled and specified interface doesn't support IPv4.";
                        err = [[self badParamError:msg] retain];
                        
                        [pool drain];
                        return_from_block;
                }
                
        // Whether IP version 4 protocol is enabled
                BOOL enableIPv4 = !isIPv4Disabled && (interface4 != nil);
        
        // Whether IP version 6 protocol is enabled
                BOOL enableIPv6 = !isIPv6Disabled && (interface6 != nil);
                
                // Create sockets, configure, bind, and listen
        
        // If IP version 4 protocol is enabled
                if (enableIPv4)
                {
                        LogVerbose(@"Creating IPv4 socket");
            
            // Create an internal socket
                        socket4FD = createSocket(AF_INET, interface4);
                        
            // If there is not an IP version 4 socket file descriptor
                        if (socket4FD == SOCKET_NULL)
                        {
                                result = NO;
                                
                                [pool drain];
                                return_from_block;
                        }
                }
                
        // If IP version 6 protocol is enabled
                if (enableIPv6)
                {
                        LogVerbose(@"Creating IPv6 socket");
                        
            // If IP version 4 protocol is enabled but the port is zero
                        if (enableIPv4 && (port == 0))
                        {
                                // No specific port was specified, so we allowed the OS to pick an available port for us.
                                // Now we need to make sure the IPv6 socket listens on the same port as the IPv4 socket.
                                
                                struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)[interface6 bytes];
                
                // Converts the local port from host to network byte order
                                addr6->sin6_port = htons([self localPort4]);
                        }
                        
            // Create an internal socket
                        socket6FD = createSocket(AF_INET6, interface6);
                        
            // If there is not an IP version 6 file descriptor
                        if (socket6FD == SOCKET_NULL)
                        {
                                result = NO;
                                
                // If the IP version 4 socket is not null
                                if (socket4FD != SOCKET_NULL)
                                {
                                        close(socket4FD);
                                }
                                
                                [pool drain];
                                return_from_block;
                        }
                }
                
                // Create accept sources
        
        // If IP version 4 protocol is enabled
                if (enableIPv4)
                {
            // Creates a read source on the socketQueue
                        accept4Source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, socket4FD, 0, socketQueue);
                        
            
                        int socketFD = socket4FD;
            
            // Dispatch sources are used to automatically submit event handler blocks to dispatch queues in response to external events.
                        dispatch_source_t acceptSource = accept4Source;
                        
            // Sets the event handler block for the accept4Source
                        dispatch_source_set_event_handler(accept4Source, ^{
                
                                NSAutoreleasePool *eventPool = [[NSAutoreleasePool alloc] init];
                                
                                LogVerbose(@"event4Block");
                                
                // Value is 0 to 2,147,483,647
                                unsigned long i = 0;
                
                // Gets the number of pending connections to the server
                // Value is 0 to 2,147,483,647
                                unsigned long numPendingConnections = dispatch_source_get_data(acceptSource);
                                
                                LogVerbose(@"numPendingConnections: %lu", numPendingConnections);
                                
                // While accepting for parent socket file description and number of pending connections is greater than i
                                while ([self doAccept:socketFD] && (++i < numPendingConnections));
                                
                                [eventPool drain];
                        }); // END OF BLOCK
                        
            
            // Sets the cancellation handler block for the accept4Source
                        dispatch_source_set_cancel_handler(accept4Source, ^{
                                
                                LogVerbose(@"dispatch_release(accept4Source)");
                                dispatch_release(acceptSource);
                                
                                LogVerbose(@"close(socket4FD)");
                                close(socketFD);
                        }); // END OF BLOCK
                        
            
                        LogVerbose(@"dispatch_resume(accept4Source)");
            
            // Resume accepting IP version 4 connections
                        dispatch_resume(accept4Source);  
                }
                
        // If IP version 6 protocol is being utilized
                if (enableIPv6)
                {
            // Dispatch sources are used to automatically submit event
            // handler blocks to dispatch queues in response to external 
            // events.
                        accept6Source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, socket6FD, 0, socketQueue);
                        
            
                        int socketFD = socket6FD;
                        dispatch_source_t acceptSource = accept6Source;
                        
            
            // Sets the event handler block for the accept6Source
                        dispatch_source_set_event_handler(accept6Source, ^{

                                NSAutoreleasePool *eventPool = [[NSAutoreleasePool alloc] init];
                                
                                LogVerbose(@"event6Block");
                                
                // Value is 0 to 2,147,483,647
                                unsigned long i = 0;
                
                // Value is 0 to 2,147,483,647
                                unsigned long numPendingConnections = dispatch_source_get_data(acceptSource);
                                
                                LogVerbose(@"numPendingConnections: %lu", numPendingConnections);
                                
                                while ([self doAccept:socketFD] && (++i < numPendingConnections));
                                
                                [eventPool drain];
                        }); // END OF BLOCK
                        
            
            // Sets the cancellation handler block for the accept6Source
                        dispatch_source_set_cancel_handler(accept6Source, ^{
                                
                                LogVerbose(@"dispatch_release(accept6Source)");
                                dispatch_release(acceptSource);
                                
                                LogVerbose(@"close(socket6FD)");
                                close(socketFD);
                        }); // END OF BLOCK
                        
                        LogVerbose(@"dispatch_resume(accept6Source)");
            
            // Resume accepting IP version 6 connections
                        dispatch_resume(accept6Source); 
                }
                
        // If set, socket has been started (accepting/connecting)
                flags |= kSocketStarted;
                [pool drain];
        };
        
    // Returns the queue on which the currently executing block is running.
    // In this case, check if the socketQueue is currently running the block
        if (dispatch_get_current_queue() == socketQueue)
    {
                block();  // executes block on the socketQueue
        }else{
        
        // Dispatches block for asynchronous execution on the socketQueue
                dispatch_sync(socketQueue, block);
    }
    
    
        if (result == NO)
        {
                LogInfo(@"Error in accept: %@", err);
                
                if (errPtr)
        {
                        *errPtr = [err autorelease];
            
                }else{
            
                        [err release];
        }
        }
        
        return result;
}
- (BOOL) acceptOnPort: (UInt16)  port
error: (NSError **)  errPtr 

Tells the socket to begin listening and accepting connections on the given port.

When a connection is accepted, a new instance of GCDAsyncSocket will be spawned to handle it, and the socket:didAcceptNewSocket: delegate method will be invoked.

The socket will listen on all available interfaces (e.g. wifi, ethernet, etc) param (UInt16) port param NSError returns BOOL

Whether accept connection on a port (listen socket) port - A port number at which the receiver should accept connections. errPtr - The address of an NSError object pointer. In the event of an error, the pointer will be set to the NSError object describing the error

param UInt16 param NSError returns BOOL

Definition at line 2239 of file GCDAsyncSocket.m.

                    :(UInt16)port error:(NSError **)errPtr
{
        return [self acceptOnInterface:nil port:port error:errPtr];
}
- (BOOL) autoDisconnectOnClosedReadStream

Traditionally sockets are not closed until the conversation is over. However, it is technically possible for the remote endpoint to close its write stream. Our socket would then be notified that there is no more data to be read, but our socket would still be writeable and the remote endpoint could continue to receive our data.

The argument for this confusing functionality stems from the idea that a client could shut down its write stream after sending a request to the server, thus notifying the server there are to be no further requests. In practice, however, this technique did little to help server developers.

To make matters worse, from a TCP perspective there is no way to tell the difference from a read stream close and a full socket close. They both result in the TCP stack receiving a FIN packet. The only way to tell is by continuing to write to the socket. If it was only a read stream close, then writes will continue to work. Otherwise an error will be occur shortly (when the remote end sends us a RST (reset) packet).

In addition to the technical challenges and confusion, many high level socket/stream API's provide no support for dealing with the problem. If the read stream is closed, the API immediately declares the socket to be closed, and shuts down the write stream as well. In fact, this is what Apple's CFStream API does. It might sound like poor design at first, but in fact it simplifies development.

The vast majority of the time if the read stream is closed it's because the remote endpoint closed its socket. Thus it actually makes sense to close the socket at this point. And in fact this is what most networking developers want and expect to happen. However, if you are writing a server that interacts with a plethora of clients, you might encounter a client that uses the discouraged technique of shutting down its write stream. If this is the case, you can set this property to NO, and make use of the socketDidCloseReadStream delegate method.

The default value is YES. Whether automatically disconnecting upon the closing of a read stream returns BOOL

Whether to automatically disconnect upon closing the read stream returns BOOL

Definition at line 1922 of file GCDAsyncSocket.m.

{
        // Note: YES means kAllowHalfDuplexConnection is OFF
        
    // Returns the queue on which the currently executing block is running.
    // In this case, check if the socketQueue is currently running the block
        if (dispatch_get_current_queue() == socketQueue)
        {
                return ((config & kAllowHalfDuplexConnection) == 0);
        }
        else // if the current queue is not the socketQueue
        {
        // Gets the result from the block
                __block BOOL result;
                
        //  Submits a block for synchronous execution on a dispatch queue.
                dispatch_sync(socketQueue, ^{
                        result = ((config & kAllowHalfDuplexConnection) == 0);
                }); // END OF BLOCK
                
                return result;
        }
}
- (NSError *) badConfigError: (NSString *)  msg

param msg returns NSError

- (NSError *) badParamError: (NSString *)  msg

param msg returns NSError

- (void) close

Close the connection

- (void) closeWithError: (NSError *)  error

param NSError

- (void) completeCurrentRead

Complete the current read

- (void) completeCurrentWrite

Completes the current write

- (NSData *) connectedAddress

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.

returns NSData

- (NSString *) connectedHost

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 *) connectedHost4

returns NSString

- (NSString *) connectedHost6

returns NSString

- (NSString *) connectedHostFromSocket4: (int)  socketFD

param int returns NSString

- (NSString *) connectedHostFromSocket6: (int)  socketFD

param int returns NSString

- (UInt16) connectedPort

returns UInt16

- (UInt16) connectedPort4

returns unsigned 16-bit integer

- (UInt16) connectedPort6

returns unsigned 16-bit integer

- (UInt16) connectedPortFromSocket4: (int)  socketFD

param int returns unsigned 16-bit integer

- (UInt16) connectedPortFromSocket6: (int)  socketFD

param int returns unsigned 16-bit integer

- (NSError *) connectTimeoutError

returns NSError

- (BOOL) connectToAddress: (NSData *)  remoteAddr
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];

This method invokes connectToAdd

- (BOOL) connectToAddress: (NSData *)  remoteAddr
viaInterface: (NSString *)  interface
withTimeout: (NSTimeInterval)  timeout
error: (NSError **)  errPtr 

Connects to the given address, using the specified interface and timeout.

The address is 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];

The interface may be a name (e.g. "en1" or "lo0") or the corresponding IP address (e.g. "192.168.4.35"). The interface may also be used to specify the local port (see below).

The timeout is optional. To not time out use a negative time interval.

This method will return NO if an error is detected, and set the error pointer (if one was given). Possible errors would be a nil host, invalid interface, or socket is already connected.

If no errors are detected, this method will start a background connect operation and immediately return YES. The delegate callbacks are used to notify you when the socket connects, or if the host was unreachable.

Since this class supports queued reads and writes, you can immediately start reading and/or writing. All read/write operations will be queued, and upon socket connection, the operations will be dequeued and processed in order.

The interface may optionally contain a port number at the end of the string, separated by a colon. This allows you to specify the local port that should be used for the outgoing connection. (read paragraph to end) To specify both interface and local port: "en1:8082" or "192.168.4.35:2424". To specify only local port: ":8082". Please note this is an advanced feature, and is somewhat hidden on purpose. You should understand that 99.999% of the time you should NOT specify the local port for an outgoing connection. If you think you need to, there is a very good chance you have a fundamental misunderstanding somewhere. Local ports do NOT need to match remote ports. In fact, they almost never do. This feature is here for networking professionals using very advanced techniques.

param NSData param NSString param NSTimeInterval param NSError returns BOOL

- (BOOL) connectToAddress: (NSData *)  remoteAddr
withTimeout: (NSTimeInterval)  timeout
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. param NSData param NSTimeInterval param NSError returns BOOL

- (BOOL) connectToHost: (NSString *)  host
onPort: (UInt16)  port
error: (NSError **)  errPtr 

Connects to the given host and port.

This method invokes connectToHost:onPort:viaInterface:withTimeout:error: and uses the default interface, and no timeout. param NSString param UInt16 returns BOOL

Whether can connect to a host on a particular port host - A DNS name or IP address to which the receiver should connect. Both IPv4 and IPv6 addresses are supported. port - A port number to which the receiver should connect. errPtr - The address of an NSError object pointer. In the event of an error, the pointer will be set to the NSError object describing the error.

param NSString param UInt16 param NSError returns BOOL

Definition at line 2963 of file GCDAsyncSocket.m.

                     :(NSString*)host onPort:(UInt16)port error:(NSError **)errPtr
{
    
        return [self connectToHost:host onPort:port withTimeout:-1 error:errPtr];
}
- (BOOL) connectToHost: (NSString *)  host
onPort: (UInt16)  port
viaInterface: (NSString *)  interface
withTimeout: (NSTimeInterval)  timeout
error: (NSError **)  errPtr 

Connects to the given host & port, via the optional interface, with an optional timeout.

The host may be a domain name (e.g. "deusty.com") or an IP address string (e.g. "192.168.0.2"). The interface may be a name (e.g. "en1" or "lo0") or the corresponding IP address (e.g. "192.168.4.35"). The interface may also be used to specify the local port (see below).

To not time out use a negative time interval.

This method will return NO if an error is detected, and set the error pointer (if one was given). Possible errors would be a nil host, invalid interface, or socket is already connected.

If no errors are detected, this method will start a background connect operation and immediately return YES. The delegate callbacks are used to notify you when the socket connects, or if the host was unreachable.

Since this class supports queued reads and writes, you can immediately start reading and/or writing. All read/write operations will be queued, and upon socket connection, the operations will be dequeued and processed in order.

The interface may optionally contain a port number at the end of the string, separated by a colon. This allows you to specify the local port that should be used for the outgoing connection. (read paragraph to end) To specify both interface and local port: "en1:8082" or "192.168.4.35:2424". To specify only local port: ":8082". Please note this is an advanced feature, and is somewhat hidden on purpose. You should understand that 99.999% of the time you should NOT specify the local port for an outgoing connection. If you think you need to, there is a very good chance you have a fundamental misunderstanding somewhere. Local ports do NOT need to match remote ports. In fact, they almost never do. This feature is here for networking professionals using very advanced techniques.

Whether can connect to host on specific port via a specific interface hostname - A DNS name or IP address to which the receiver should connect. Both IPv4 and IPv6 addresses are supported port - A port number to which the receiver should connect. errPtr - The address of an NSError object pointer. In the event of an error, the pointer will be set to the NSError object describing the error

param NSString param UInt16 param NSString param NSTimeInterval param NSError returns BOOL

- (BOOL) connectToHost: (NSString *)  host
onPort: (UInt16)  port
withTimeout: (NSTimeInterval)  timeout
error: (NSError **)  errPtr 

Connects to the given host and port with an optional timeout.

This method invokes connectToHost:onPort:viaInterface:withTimeout:error: and uses the default interface. param NSString param UInt16 param NSTimeInterval param NSError returns BOOL

Whether can connect to host on a specific port via a specific interface with a specific timeout

param NSString param UInt16 param NSTimeInterval param NSError returns BOOL

Definition at line 2980 of file GCDAsyncSocket.m.

                     :(NSString *)host
               onPort:(UInt16)port
          withTimeout:(NSTimeInterval)timeout
                error:(NSError **)errPtr
{
        return [self connectToHost:host onPort:port viaInterface:nil withTimeout:timeout error:errPtr];
}
- (BOOL) connectWithAddress4: (NSData *)  address4
address6: (NSData *)  address6
error: (NSError **)  errPtr 

param NSData param NSData param NSError returns BOOL

- (void) continueSSLHandshake

Continue the SSL handshake

+ (NSData *) CRData

Class method returns NSData

+ (NSData *) CRLFData

A few common line separators, for use with the readDataToData:... methods. Class method returns NSData

- (id) delegate

Gets the delegate returns id

- (dispatch_queue_t) delegateQueue

Get the delegate queue returns dispatch_queue_t

- (void) didConnect: (int)  aConnectIndex

param int

- (void) didNotConnect: (int)  aConnectIndex
error: (NSError *)  error 

param int param NSError

- (void) disconnect

Disconnects immediately (synchronously). Any pending reads or writes are dropped. If the socket is not already disconnected, the socketDidDisconnect 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) disconnectAfterReading

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) disconnectAfterReadingAndWriting

Disconnects after all pending reads and writes have completed. After calling this, the read and write methods will do nothing.

- (void) disconnectAfterWriting

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.

- (BOOL) doAccept: (int)  socketFD

param int returns boolean

- (void) doConnectTimeout
- (void) doReadData

Reads data

- (void) doReadEOF

Read until the end of file terminator

- (void) doReadTimeout
- (void) doReadTimeoutWithExtension: (NSTimeInterval)  timeoutExtension

Provides for an extension of time param NSTimeInterval

- (void) doWriteData

Writes the data to the socket

- (void) doWriteTimeout
- (void) doWriteTimeoutWithExtension: (NSTimeInterval)  timeoutExtension

param NSTimeInterval

- (void) endConnectTimeout
- (void) endCurrentRead

Stop the current read Cancel the timer and release the current writer

- (void) endCurrentWrite

Cancel the timer and release the current writer

- (NSError *) errnoError

returns NSError

- (NSError *) errnoErrorWithReason: (NSString *)  reason

param NSString returns NSError

- (NSError *) gaiError: (int)  gai_error

param int returns NSError

- (void) getDelegate: (id *)  delegatePtr
delegateQueue: (dispatch_queue_t *)  delegateQueuePtr 

Get delegate and delegate queue param id param dispatch_queue_t

Gets the delegate point and delegate queue pointer param id param dispatch_queue_t

Definition at line 1793 of file GCDAsyncSocket.m.

                   :(id *)delegatePtr delegateQueue:(dispatch_queue_t *)delegateQueuePtr
{
    
    // Returns the queue on which the currently executing block is running.
    // In this case, check if the socketQueue is currently running the block
        if (dispatch_get_current_queue() == socketQueue)
        {
        // If there is a delegate pointer
                if (delegatePtr)
        {
            *delegatePtr = delegate;
        }
        
        // If there is a delegateQueue pointer
                if (delegateQueuePtr)
        {
            *delegateQueuePtr = delegateQueue;
        }
        
        }
        else  // If the current queue is not the socketQueue
        {
        // Get the delegate pointer and delegate queue from the block
                __block id dPtr = NULL;
        
        // Delegate queue pointer
                __block dispatch_queue_t dqPtr = NULL;
                
        
        //BLOCK
        
        // Submits a block for synchronous execution on the socketQueue
                dispatch_sync(socketQueue, ^{
                        dPtr = delegate; //delegate pointer
                        dqPtr = delegateQueue; // delegate que pointer
                }); // END OF BLOCK
                
        // If there is a delegate pointer
                if (delegatePtr)
        {
            *delegatePtr = dPtr;
        }
        
        // If there is a delegateQueue pointer
                if (delegateQueuePtr)
        {
            
            *delegateQueuePtr = dqPtr;
        }
        }
}
+ (BOOL) getHost: (NSString **)  hostPtr
port: (UInt16 *)  portPtr
fromAddress: (NSData *)  address 

Class method param NSString (pointer to a pointer) param UInt16 param NSData returns BOOL

- (void) getInterfaceAddress4: (NSData **)  addr4Ptr
address6: (NSData **)  addr6Ptr
fromDescription: (NSString *)  interfaceDescription
port: (UInt16)  port 

param NSData param NSData param NSString param unsigned 16-bit integer

+ (NSString *) hostFromAddress4: (struct sockaddr_in *)  pSockaddr4

Class method param struct sockaddr_in (IP version 4) returns NSString

+ (NSString *) hostFromAddress6: (struct sockaddr_in6 *)  pSockaddr6

Class method param struct sockaddr_in6 returns NSString

+ (NSString *) hostFromAddress: (NSData *)  address

Class method Gets the host from an address param NSData returns NSString

- (id) init

GCDAsyncSocket uses the standard delegate paradigm, but executes all delegate callbacks on a given delegate dispatch queue. This allows for maximum concurrency, while at the same time providing easy thread safety.

You MUST set a delegate AND delegate dispatch queue before attempting to use the socket, or you will get an error.

The socket queue is optional. If you pass NULL, GCDAsyncSocket will automatically create it's own socket queue.

If you choose to provide a socket queue, the socket queue must not be a concurrent queue.

The delegate queue and socket queue can optionally be the same.

Initialize the GCDAsyncSocket This message initializes the receiver, setting the delegate at the same time. returns self (instance of GCDAsyncSocket)

Definition at line 1460 of file GCDAsyncSocket.m.

{
        return [self initWithDelegate:nil delegateQueue:NULL socketQueue:NULL];
}
- (id) initWithDelegate: (id)  aDelegate
delegateQueue: (dispatch_queue_t)  dq 

Initialize the GCDAsyncSocket with a delegate and delegate queue param dispatch_queue_t returns id (self)

Initialize the GCDAsyncSocket with delegate and delegate queue This message initializes the receiver, setting the delegate at the same time.

param id param dispatch_queue_t returns self (instance of GCDAsyncSocket)

Definition at line 1486 of file GCDAsyncSocket.m.

                      :(id)aDelegate delegateQueue:(dispatch_queue_t)dq
{
        return [self initWithDelegate:aDelegate delegateQueue:dq socketQueue:NULL];
}
- (id) initWithDelegate: (id)  aDelegate
delegateQueue: (dispatch_queue_t)  dq
socketQueue: (dispatch_queue_t)  sq 

Initialize the GCDAsyncSocket with a delegate, delegate queue, and socket queue param id param dispatch_queue_t param dispatch_queue_t returns id

Initialize the GCDAsyncSocket with delegate, delegate queue, and socket queue This message initializes the receiver, setting the delegate at the same time.

param id param dispatch_queue_t param dispatch_queue_t returns self (instance of GCDAsyncSocket)

Definition at line 1500 of file GCDAsyncSocket.m.

                      :(id)aDelegate delegateQueue:(dispatch_queue_t)dq socketQueue:(dispatch_queue_t)sq
{
        if((self = [super init]))
        {
        // Sets the socket delegate
                delegate = aDelegate;
                
        // Test if there is a delegat queue
                if (dq)
                {
            // Increment the reference count of the delegate queue
                        dispatch_retain(dq);
                        delegateQueue = dq;
                }
                
                socket4FD = SOCKET_NULL;
                socket6FD = SOCKET_NULL;
                connectIndex = 0;
                
                if (sq) // socket queue
                {
            // Make sure the socket queue is not a global concurrence queue
                        NSString *assertMsg = @"The given socketQueue parameter must not be a concurrent queue.";
                        
            
            // Test whether the socket queue is not equal to the global queue values
                        NSAssert(sq != dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), assertMsg);
                        NSAssert(sq != dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), assertMsg);
                        NSAssert(sq != dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), assertMsg);
                        
                        dispatch_retain(sq);  // Increments the reference to socket queue
                        socketQueue = sq;
                }
                else  // if there isn't a socket queue, then create one
                {
            // Creates the Grand Central Dispatch AsyncSocket queue
                        socketQueue = dispatch_queue_create("GCDAsyncSocket", NULL);
                }
                
        // Create readqueue mutable array with capacity of 5
                readQueue = [[NSMutableArray alloc] initWithCapacity:5];
                currentRead = nil;
                
        // Create writequeue mutable array with capacity of 5
                writeQueue = [[NSMutableArray alloc] initWithCapacity:5];
                currentWrite = nil;
                
        // Create partial read buffer for the host message
                partialReadBuffer = [[NSMutableData alloc] init];
        }
        return self;
}
- (id) initWithSocketQueue: (dispatch_queue_t)  sq

Initialize the GCDAsyncSocket with a socket queue

param dispatch_queue_t returns id (self)

Initialize the GCDAsyncSocket with a socket queue

param dispatch_queue_t returns self (instance of GCDAsyncSocket)

Definition at line 1471 of file GCDAsyncSocket.m.

                         :(dispatch_queue_t)sq
{
    
    // This message initializes the receiver, setting the delegate at the same time.
        return [self initWithDelegate:nil delegateQueue:NULL socketQueue:sq];
}
- (BOOL) isConnected

returns BOOL

- (BOOL) isDisconnected

Returns whether the socket is disconnected or connected.

A disconnected socket may be recycled. That is, it can used again for connecting or listening.

If a socket is in the process of connecting, it may be neither disconnected nor connected.

- (BOOL) isIPv4

Returns whether the socket is IPv4 or IPv6. An accepting socket may be both. returns BOOL

- (BOOL) isIPv4Enabled

By default, both IPv4 and IPv6 are enabled.

For accepting incoming connections, this means GCDAsyncSocket automatically supports both protocols, and can simulataneously accept incoming connections on either protocol.

For outgoing connections, this means GCDAsyncSocket can connect to remote hosts running either protocol. If a DNS lookup returns only IPv4 results, GCDAsyncSocket will automatically use IPv4. If a DNS lookup returns only IPv6 results, GCDAsyncSocket will automatically use IPv6. If a DNS lookup returns both IPv4 and IPv6 results, the preferred protocol will be chosen. By default, the preferred protocol is IPv4, but may be configured as desired. Whether IP version 4 is enabled returns BOOL

Returns whether IP version 4 is enabled returns BOOL

Definition at line 1981 of file GCDAsyncSocket.m.

{
        // Note: YES means kIPv4Disabled is OFF
        
    // Returns the queue on which the currently executing block is running.
    // In this case, check if the socketQueue is currently running the block
        if (dispatch_get_current_queue() == socketQueue)
        {
                return ((config & kIPv4Disabled) == 0);
        }
        else
        {
        // Gets the result from the block
                __block BOOL result;
                
        // Submits a block for synchronous execution on a dispatch queue.
                dispatch_sync(socketQueue, ^{
            
            // If set, IPv4 is disabled
                        result = ((config & kIPv4Disabled) == 0);
            
                }); // END OF BLOCK
                
                return result;
        }
}
- (BOOL) isIPv4PreferredOverIPv6

Whether IP version 4 protocol is preferred over IP version 6 protocol returns BOOL

Whether IP version 4 is preferred over IP version 6 returns BOOL

Definition at line 2105 of file GCDAsyncSocket.m.

{
        // Note: YES means kPreferIPv6 is OFF
        
    // Returns the queue on which the currently executing block is running.
    // In this case, check if the socketQueue is currently running the block
        if (dispatch_get_current_queue() == socketQueue)
        {
                return ((config & kPreferIPv6) == 0);
        }
        else
        {
        // Gets the result from the block
                __block BOOL result;
                
        // Submits a block for synchronous execution on a dispatch queue.
                dispatch_sync(socketQueue, ^{
                        result = ((config & kPreferIPv6) == 0);
                }); // END OF BLOCK
                
                return result;
        }
}
- (BOOL) isIPv6

returns BOOL

- (BOOL) isIPv6Enabled

Whether IP version 6 protocol is enabled returns BOOL

Returns whether IP version 6 is enabled returns BOOL

Definition at line 2044 of file GCDAsyncSocket.m.

{
        // Note: YES means kIPv6Disabled is OFF
        
    
    // Returns the queue on which the currently executing block is running.
    // In this case, check if the socketQueue is currently running the block
        if (dispatch_get_current_queue() == socketQueue)
        {
                return ((config & kIPv6Disabled) == 0);
        }
        else
        {
        // Gets the result from the block
                __block BOOL result;
                
        // Submits a block for synchronous execution on a dispatch queue.
                dispatch_sync(socketQueue, ^{
                        result = ((config & kIPv6Disabled) == 0);
                }); // END OF BLOCK
                
                return result;
        }
}
+ (NSData *) LFData

Class method returns NSData

- (NSData *) localAddress

returns NSData

- (NSString *) localHost

returns NSString

- (NSString *) localHost4

returns NSString

- (NSString *) localHost6

returns NSString

- (NSString *) localHostFromSocket4: (int)  socketFD

param int returns NSString

- (NSString *) localHostFromSocket6: (int)  socketFD

param int returns NSString

- (UInt16) localPort

returns UInt16

- (UInt16) localPort4

returns unsigned 16-bit integer

- (UInt16) localPort6

returns unsigned 16-bit integer

- (UInt16) localPortFromSocket4: (int)  socketFD

param int returns unsigned 16-bit integer

- (UInt16) localPortFromSocket6: (int)  socketFD

param int returns unsigned 16-bit integer

- (void) lookup: (int)  aConnectIndex
didFail: (NSError *)  error 

param int param NSError

- (void) lookup: (int)  aConnectIndex
didSucceedWithAddress4: (NSData *)  address4
address6: (NSData *)  address6 

param int param NSData param NSData

- (void) lookup: (int)  aConnectIndex
host: (NSString *)  host
port: (UInt16)  port 

param int param NSString param UInt16

- (void) maybeClose

Determine if can close the connection

- (void) maybeDequeueRead

Conditionally starts a new read.

It is called when:

  • a user requests a read
  • after a read request has finished (to handle the next request)
  • immediately after the socket opens to handle any pending requests

This method also handles auto-disconnect post read completion.

- (void) maybeDequeueWrite

Conditionally starts a new write.

It is called when:

  • a user requests a write
  • after a write request has finished (to handle the next request)
  • immediately after the socket opens to handle any pending requests

This method also handles auto-disconnect post read/write completion.

- (void) maybeStartTLS

Conditionally start trasport layer security

- (NSError *) otherError: (NSString *)  msg

param msg returns NSError

- (void) performBlock: (dispatch_block_t)  block

It's not thread-safe to access certain variables from outside the socket's internal queue.

For example, the socket file descriptor. File descriptors are simply integers which reference an index in the per-process file table. However, when one requests a new file descriptor (by opening a file or socket), the file descriptor returned is guaranteed to be the lowest numbered unused descriptor. So if we're not careful, the following could be possible:

  • Thread A invokes a method which returns the socket's file descriptor.
  • The socket is closed via the socket's internal queue on thread B.
  • Thread C opens a file, and subsequently receives the file descriptor that was previously the socket's FD.
  • Thread A is now accessing/altering the file instead of the socket.

In addition to this, other variables are not actually objects, and thus cannot be retained/released or even autoreleased. An example is the sslContext, of type SSLContextRef, which is actually a malloc'd struct.

Although there are internal variables that make it difficult to maintain thread-safety, it is important to provide access to these variables to ensure this class can be used in a wide array of environments. This method helps to accomplish this by invoking the current block on the socket's internal queue. The methods below can be invoked from within the block to access those generally thread-unsafe internal variables in a thread-safe manner. The given block will be invoked synchronously on the socket's internal queue.

If you save references to any protected variables and use them outside the block, you do so at your own peril.

+ (UInt16) portFromAddress4: (struct sockaddr_in *)  pSockaddr4

Class method param struck sockaddr_in (IP version 4) returns unsigned 16-bit integer

+ (UInt16) portFromAddress6: (struct sockaddr_in6 *)  pSockaddr6

Class method param struct sockaddr_in6 (IP version 6) returns UInt16

+ (UInt16) portFromAddress: (NSData *)  address

Class method Get the port from an address param NSData returns UInt16

- (void) readDataToData: (NSData *)  data
withTimeout: (NSTimeInterval)  timeout
buffer: (NSMutableData *)  buffer
bufferOffset: (NSUInteger)  offset
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.

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 GCDAsyncSocketReadMaxedOutError. 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 socket: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. 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 socket: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
maxLength: (NSUInteger)  length
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 GCDAsyncSocketReadMaxedOutError. 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
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) readDataToLength: (NSUInteger)  length
withTimeout: (NSTimeInterval)  timeout
buffer: (NSMutableData *)  buffer
bufferOffset: (NSUInteger)  offset
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 socket: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
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) readDataWithTimeout: (NSTimeInterval)  timeout
buffer: (NSMutableData *)  buffer
bufferOffset: (NSUInteger)  offset
maxLength: (NSUInteger)  length
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 socket: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.

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 socket: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
tag: (long)  tag 

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) resumeReadSource

Resumes the read source

- (void) resumeWriteSource

Resumes the write source

- (void) setAutoDisconnectOnClosedReadStream: (BOOL)  flag

Sets the flag for whether automatically disconnecting upon the closing of a read stream param BOOL

Sets the flag for whether to automatically disconnect upon closing the read stream param BOOL

Definition at line 1951 of file GCDAsyncSocket.m.

                                           :(BOOL)flag
{
        // Note: YES means kAllowHalfDuplexConnection is OFF
        
    // The prototype of blocks submitted to dispatch queues, which take no arguments and have no return value.
        dispatch_block_t block = ^{
                
                if (flag)
        {
                        config &= ~kAllowHalfDuplexConnection;
                }else{
                        config |= kAllowHalfDuplexConnection;
        }
        }; // END OF BLOCK
        
    // Returns the queue on which the currently executing block is running.
    // In this case, check if the socketQueue is currently running the block
        if (dispatch_get_current_queue() == socketQueue)
    {
                block(); // submits the block to the socketQueue
        }else{
        // Submits block to the socketQueue asynchronously because it is not the current queue.
                dispatch_async(socketQueue, block);
    }
}
- (void) setDelegate: (id)  newDelegate

Sets the delegate param id

Definition at line 1677 of file GCDAsyncSocket.m.

                   :(id)newDelegate
{
    // Sets the delegate as the newDelegate for asynchronous execution of blocks
        [self setDelegate:newDelegate synchronously:NO];
}
- (void) setDelegate: (id)  newDelegate
delegateQueue: (dispatch_queue_t)  newDelegateQueue 

Set the delegate and delegate queue param id param dispatch_queue_t

Sets the delegate and delegate queue param id param dispatch_queue_t

Definition at line 1902 of file GCDAsyncSocket.m.

                   :(id)newDelegate delegateQueue:(dispatch_queue_t)newDelegateQueue
{
    
        [self setDelegate:newDelegate delegateQueue:newDelegateQueue synchronously:NO];
}
- (void) setDelegateQueue: (dispatch_queue_t)  newDelegateQueue

Set the delegate queue param dispatch_queue_t

Sets the delegate queue param dispatch_queue_t

Definition at line 1772 of file GCDAsyncSocket.m.

                        :(dispatch_queue_t)newDelegateQueue
{
    // Set the delegate queue to the new delegate queue for asynchronous execution of blocks
        [self setDelegateQueue:newDelegateQueue synchronously:NO];
}
- (void) setIPv4Enabled: (BOOL)  flag

Set the flag for whether IP version 4 protocol is enabled param BOOL

Sets the flag to enable IP version 4 param BOOL

Definition at line 2012 of file GCDAsyncSocket.m.

                      :(BOOL)flag
{
        // Note: YES means kIPv4Disabled is OFF
        
    // The prototype of blocks submitted to dispatch queues, which take no arguments and have no return value.
        dispatch_block_t block = ^{
                
                if (flag)
        {
                        config &= ~kIPv4Disabled;
                }else{
                        config |= kIPv4Disabled;
        }
        }; // END OF BLOCK
        
    // Returns the queue on which the currently executing block is running.
    // In this case, check if the socketQueue is currently running the block
        if (dispatch_get_current_queue() == socketQueue)
    {
                block(); // submit block for execution
        }else{
        
        // Submits block for execution
                dispatch_async(socketQueue, block);
    }
}
- (void) setIPv6Enabled: (BOOL)  flag

Set the flag for whether IP version 6 protocol is enabled param BOOL

Sets the flag to enable IP version 6 param BOOL

Definition at line 2073 of file GCDAsyncSocket.m.

                      :(BOOL)flag
{
        // Note: YES means kIPv6Disabled is OFF
        
    // The prototype of blocks submitted to dispatch queues, which take no arguments and have no return value.
        dispatch_block_t block = ^{
                
                if (flag)
        {
                        config &= ~kIPv6Disabled;
            
                }else{
                        config |= kIPv6Disabled;
        }
        }; // END OF BLOCK
        
    // Returns the queue on which the currently executing block is running.
    // In this case, check if the socketQueue is currently running the block
        if (dispatch_get_current_queue() == socketQueue)
    {
                block(); // submit block for execution on the queue
        }else{
        
        // Executes block asynchronously on the socketQueue
                dispatch_async(socketQueue, block);
    }
}
- (void) setPreferIPv4OverIPv6: (BOOL)  flag

Set the flag for whether IP version 4 protocol is preferred over IP version 6 param BOOL

Set the flag for whether IP version 4 is preferred over IP version 6 param BOOL

Definition at line 2133 of file GCDAsyncSocket.m.

                             :(BOOL)flag
{
        // Note: YES means kPreferIPv6 is OFF
        
    //  The prototype of blocks submitted to dispatch queues, which take no arguments and have no return value.
        dispatch_block_t block = ^{
                
                if (flag)
        {
                        config &= ~kPreferIPv6;
                }else{
                        config |= kPreferIPv6;
        }
        };  // END OF BLOCK
        
    // Returns the queue on which the currently executing block is running.
    // In this case, check if the socketQueue is currently running the block
        if (dispatch_get_current_queue() == socketQueue)
    {
                block(); // executions the block
        
        }else{
        
        // Executes the block asynchronously on the socketQueue
                dispatch_async(socketQueue, block);
    }
}
- (void) setupReadAndWriteSourcesForNewlyConnectedSocket: (int)  socketFD

Setup the read and write source for a newly connected socket param int

- (void) setupReadTimerWithTimeout: (NSTimeInterval)  timeout

Setup the readtime with a time interaval param NSTimeInterval

- (void) setupWriteTimerWithTimeout: (NSTimeInterval)  timeout

param NSTimeInterval

- (void) setUserData: (id)  arbitraryUserData

param id

Sets userData param id

Definition at line 2199 of file GCDAsyncSocket.m.

                   :(id)arbitraryUserData
{
    // defines block as a dispatch_block_t type
    // doesn't accept any arguements
        dispatch_block_t block = ^{
                
                if (userData != arbitraryUserData)
                {
                        [userData release];
                        userData = [arbitraryUserData retain];
                }
        }; //end of block
    
    // Returns the queue on which the currently executing block is running.
    // In this case, check if the socketQueue is currently running the block
        if (dispatch_get_current_queue() == socketQueue)
    {
                block(); // executes the block
        
    }else{
        
        // Executes the block asychronously on the socketQueue
                dispatch_async(socketQueue, block);
    }
}
- (int) socket4FD

returns int

- (int) socket6FD

returns int

- (int) socketFD

These methods are only available from within the context of a performBlock: invocation. See the documentation for the performBlock: method above.

Provides access to the socket's file descriptor(s). If the socket is a server socket (is accepting incoming connections), it might actually have multiple internal socket file descriptors - one for IPv4 and one for IPv6.

- (SSLContextRef) sslContext

This method is only available from within the context of a performBlock: invocation. See the documentation for the performBlock: method above.

Provides access to the socket's SSLContext, if SSL/TLS has been started on the socket.

- (void) startConnectTimeout: (NSTimeInterval)  timeout

param NSTimeInterval

- (void) startTLS: (NSDictionary *)  tlsSettings

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) suspendReadSource

Suspends the read source

- (void) suspendWriteSource

Suspends the write source

- (void) synchronouslySetDelegate: (id)  newDelegate

Synchronously sets the delegate param id

Set the delegate as a new delegate param id

Definition at line 1687 of file GCDAsyncSocket.m.

                                :(id)newDelegate
{
    // Set the delegate as the newDelegate for synchronous execution of blocks
        [self setDelegate:newDelegate synchronously:YES];
}
- (void) synchronouslySetDelegate: (id)  newDelegate
delegateQueue: (dispatch_queue_t)  newDelegateQueue 

Synchronously set the delegate and delegate queue param id param dispatch_queue_t

Set delegate for delgate queuue param id param dispatch_queue_t

Definition at line 1913 of file GCDAsyncSocket.m.

                                :(id)newDelegate delegateQueue:(dispatch_queue_t)newDelegateQueue
{
        [self setDelegate:newDelegate delegateQueue:newDelegateQueue synchronously:YES];
}
- (void) synchronouslySetDelegateQueue: (dispatch_queue_t)  newDelegateQueue

param dispatch_queue_t

Sets the delegate queue param dispatch_queue_t

Definition at line 1782 of file GCDAsyncSocket.m.

                                     :(dispatch_queue_t)newDelegateQueue
{
    // Set the delegate queue to the new delegate queue for synchronous execution of blocks
        [self setDelegateQueue:newDelegateQueue synchronously:YES];
}
- (id) userData

User data allows you to associate arbitrary information with the socket. This data is not used internally by socket in any way. returns id

- (void) writeData: (NSData *)  data
withTimeout: (NSTimeInterval)  timeout
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.

+ (NSData *) ZeroData

Class method returns NSData


Field Documentation

- (dispatch_source_t) accept4Source [protected]

Dispatch sources are used to automatically submit event handler blocks to dispatch queues in response to external events.

Definition at line 106 of file GCDAsyncSocket.h.

- (dispatch_source_t) accept6Source [protected]

Dispatch sources are used to automatically submit event handler blocks to dispatch queues in response to external events.

Definition at line 111 of file GCDAsyncSocket.h.

- (UInt16) config [protected]

Definition at line 62 of file GCDAsyncSocket.h.

- (int) connectIndex [protected]

Definition at line 85 of file GCDAsyncSocket.h.

- (NSData*) connectInterface4 [protected]

Object-oriented wrappers for byte buffers IP version 4 interface

Definition at line 91 of file GCDAsyncSocket.h.

- (NSData*) connectInterface6 [protected]

IP version 6 interface

Definition at line 96 of file GCDAsyncSocket.h.

- (dispatch_source_t) connectTimer [protected]

Dispatch sources are used to automatically submit event handler blocks to dispatch queues in response to external events.

Definition at line 116 of file GCDAsyncSocket.h.

- (GCDAsyncReadPacket*) currentRead [protected]

the read packet

Definition at line 153 of file GCDAsyncSocket.h.

the write packet

Definition at line 158 of file GCDAsyncSocket.h.

- (id) delegate [protected]

Gets the delegate off the socketQueue returns id

Definition at line 67 of file GCDAsyncSocket.h.

- (dispatch_queue_t) delegateQueue [protected]

Dispatch queues are lightweight objects to which blocks may be submitted. The system manages a pool of threads which process dispatch queues and invoke blocks submitted to them.

Gets the delegateQueue returns dispatch_queue_t

Definition at line 73 of file GCDAsyncSocket.h.

- (UInt16) flags [protected]

Definition at line 56 of file GCDAsyncSocket.h.

- (NSMutableData*) partialReadBuffer [protected]

A partial read buffer for buffering the host request

Definition at line 169 of file GCDAsyncSocket.h.

- (NSMutableArray*) readQueue [protected]

The read queue

Definition at line 142 of file GCDAsyncSocket.h.

- (dispatch_source_t) readSource [protected]

Dispatch sources are used to automatically submit event handler blocks to dispatch queues in response to external events.

Definition at line 121 of file GCDAsyncSocket.h.

- (dispatch_source_t) readTimer [protected]

Dispatch sources are used to automatically submit event handler blocks to dispatch queues in response to external events.

Definition at line 131 of file GCDAsyncSocket.h.

- (int) socket4FD [protected]

IP version 4 socket file descriptor

Definition at line 78 of file GCDAsyncSocket.h.

- (int) socket6FD [protected]

IP version 6 socket file descriptor

Definition at line 83 of file GCDAsyncSocket.h.

- (unsigned long) socketFDBytesAvailable [protected]

socket file descriptor bytes available Value is 0 to 2,147,483,647

Definition at line 164 of file GCDAsyncSocket.h.

- (dispatch_queue_t) socketQueue [protected]

The dispatch queue upon which blocks are submitted

Definition at line 101 of file GCDAsyncSocket.h.

- (SSLContextRef) sslContext [protected]

the SSL context reference

Definition at line 193 of file GCDAsyncSocket.h.

- (NSMutableData*) sslReadBuffer [protected]

The SSL read buffer for buffering the host response

Definition at line 198 of file GCDAsyncSocket.h.

- (size_t) sslWriteCachedLength [protected]

size of the SSL write cache

Definition at line 203 of file GCDAsyncSocket.h.

- (id) userData [protected]

user data

Gets the userData User data allows you to associate arbitrary information with the socket. This data is not used internally by socket in any way. returns id

Definition at line 210 of file GCDAsyncSocket.h.

- (NSMutableArray*) writeQueue [protected]

the write queue

Definition at line 147 of file GCDAsyncSocket.h.

- (dispatch_source_t) writeSource [protected]

Dispatch sources are used to automatically submit event handler blocks to dispatch queues in response to external events.

Definition at line 126 of file GCDAsyncSocket.h.

- (dispatch_source_t) writeTimer [protected]

Dispatch sources are used to automatically submit event handler blocks to dispatch queues in response to external events.

Definition at line 136 of file GCDAsyncSocket.h.


The documentation for this class was generated from the following files:
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Properties Defines