Reference_GCDAsyncSocket

田永春
2023-12-01

GCDAsyncSocket是一个TCP套接字库建立在中央调度。该项目还包含一个基于RunLoop版本,以及UDP套接字库。

CocoaAsyncSocket项目是一个成熟的开源框架,自2003年以来已经存在。因此它已经受益于各种各样的网络开发人员提交的代码或建议的功能。项目的目标是创建功能强大,但易于使用的套接字库。


GCDAsyncSocket的具体功能包括:

经典delegate-style支持.

以下所有结果调用你的委托方法:连接,接受,完成阅读,编写完成,进展,断开,错误,等。委托方法包括一个套接字参数,允许您区分许多实例。

委托调度。
  可配置的dispatch_queue每个委托方法调用。这允许并行插座IO和数据处理,以及简单的线程安全。
排队阻塞读和写,可选的超时。
  你告诉它读或写什么,当它结束的时候,它就会给你打电话。
自动套接字接受。
  如果你告诉它接受连接,它就会给你打电话本身为每个连接的新实例。当然,你可以立即断开。
自动支持IPv4和IPv6。
SSL / TLS的支持。
建立在最新的技术,如kqueues。
独立的一个类。
  你不需要把系统在溪流或套接字。类处理的。

GCDAsyncSocket更强大的特性之一是它的排队结构。这允许您控制套接字你方便的时候,而不是当套接字告诉你它是准备好了。几个例子:

// Start asynchronous connection.
// The method below will return immediately,
// and the delegate method socket:didConnectToHost:port: will
// be invoked when the connection has completed.
[asyncSocket connectToHost:host onPort:port error:nil];

// At this moment in time, the socket is not yet connected.
// It has just started the asynchronous connection attempt.
// But AsyncSocket was designed to make socket programming easier for you.
// You are free to start reading/writing if it is convenient for you.
// So we are going to start the read request for our message header now.
// The read request will automatically be queued.
// And after the socket connects, this read request will automatically be dequeued and executed.
[asyncSocket readDataToLength:LENGTH_HEADER withTimeout:TIMEOUT_NONE tag:TAG_HEADER];

此外,您可以很方便的调用多个读/写请求。

// Start asynchronous write operation
[asyncSocket writeData:msgHeader withTimeout:TIMEOUT_NONE tag:TAG_HEADER];

// We don't have to wait for that write to complete before starting the next one
[asyncSocket writeData:msgBody withTimeout:TIMEOUT_NONE tag:TAG_BODY];
// Start asynchronous read operation.
// Read and ignore the welcome message.
[asyncSocket readDataToData:msgSeparator withTimeout:TIMEOUT_NONE tag:TAG_WELCOME];

// We don't have to wait for that read to complete before starting the next one.
// Read server capabilities.
[asyncSocket readDataToData:msgSeparator withTimeout:TIMEOUT_NONE tag:TAG_CAPABILITIES];
排队架构甚至延伸到SSL / TLS的支持!

// Send startTLS confirmation ACK.
// Remember this is an asynchronous operation.
[asyncSocket writeData:ack withTimeout:TIMEOUT_NONE tag:TAG_ACK];

// We don't have to wait for the write to complete before invoking startTLS.
// The socket will automatically queue the operation, and wait for previous reads/writes to complete.
// Once that has happened, the upgrade to SSL/TLS will automatically start.
[asyncSocket startTLS:tlsSettings];

// Again, we don't have to wait for the security handshakes to complete.
// We can immediately queue our next operation if it's convenient for us.
// So we can start reading the next request from the client.
// This read will occur over a secure connection.
[asyncSocket readDataToData:msgSeparator withTimeout:TIMEOUT_NONE tag:TAG_MSG];
大多数操作超时是可选的参数。

除了这一点,你可能已经注意到标签参数。一旦读/写操作完成,你通过读/写操作期间的标签会通过委托方法传回给你。它不通过套接字发送或从套接字读取。它旨在帮助简化您的委托方法中的代码。例如,您的委托方法可能看起来像这样:

#define TAG_WELCOME 10
#define TAG_CAPABILITIES 11
#define TAG_MSG 12

... 

- (void)socket:(AsyncSocket *)sender didReadData:(NSData *)data withTag:(long)tag
{
    if (tag == TAG_WELCOME)
    {
        // Ignore welcome message
    }
    else if (tag == TAG_CAPABILITIES)
    {
        [self processCapabilities:data];
    }
    else if (tag == TAG_MSG)
    {
        [self processMessage:data];
    }
}

GCDAsyncSocket是线程安全的。


委派方法
  
  GCDAsyncSocket是异步的。所以对于大多数的方法,当你启动一个操作在一个套接字(连接,接受、阅读、写作)方法将会立即返回,和行动的结果将通过相应的委托方法返回给你。

socket: didConnectToHost: port:

- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port

时调用一个套接字进行连接,准备开始读和写。主机参数将一个IP地址,而不是一个DNS名称。

socket: didReadData: withTag:

- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag

完成时调用套接字读取请求的数据到内存中。如果有一个错误则不请求。
标签参数是标记你请求时通过读取操作。例如,在readDataWithTimeout:标签:方法。

socket: didReadPartialDataOfLength: tag:

- (void)socket:(GCDAsyncSocket *)sock didReadPartialDataOfLength:(NSUInteger)partialLength tag:(long)tag

调用套接字读取的数据,但尚未完成阅读时。这将发生如果使用readDataToData:或者readDataToLength:方法。它可用于诸如更新进度条。
标签参数是标记你请求时通过读取操作。例如,在readDataToLength:withTimeout:标签:方法。

socket: shouldTimeoutReadWithTag: elapsed: bytesDone:

- (NSTimeInterval)socket:(GCDAsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag
                                                                 elapsed:(NSTimeInterval)elapsed
                                                               bytesDone:(NSUInteger)length
如果没有完成读操作达到超时。这种方法允许您选择延长超时。如果你返回一个正的时间间隔(> 0) 读取给定的超时时间将延长。如果你不实现此方法,或返回一个负的的时间间隔(< = 0)像往常一样读会超时。
运行参数是原始超时的总和,加上之前通过这种方法添加的。长度参数的字节数,一直读到目前为止读操作。
注意,这个方法可能会多次请求一个读取 如果你返回正的数字。

socket: didWriteDataWithTag:

- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag

调用套接字完成了写请求的数据时。如果有一个错误则不请求。
标签参数是标记你要求写操作时通过例如,writeData:withTimeout:标签:方法。

socket: didWritePartialDataOfLength: tag:

- (void)socket:(GCDAsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag

调用套接字写了一些数据,但还没有完成整个写操作时。它可用于诸如更新进度条。
标签参数是标记你要求写操作时通过例如,writeData:withTimeout:标签:方法。

socket: shouldTimeoutWriteWithTag: elapsed: bytesDone:

- (NSTimeInterval)socket:(GCDAsyncSocket *)sock shouldTimeoutWriteWithTag:(long)tag
                                                                  elapsed:(NSTimeInterval)elapsed
                                                                bytesDone:(NSUInteger)length;
如果一个没有完成的写操作达到超时。这种方法允许您选择延长超时。如果你返回一个正的时间间隔(> 0)写入给定的超时时间将延长。如果你不实现此方法,或返回一个负的时间间隔(< = 0)像往常一样写会超时。运行参数是原始超时的总和,加上之前通过这种方法添加的。参数长度的字节数,到目前为止已经写了写操作。
注意,这个方法可能会多次呼吁一个写如果你还积极的数字。

socketDidSecure:

- (void)socketDidSecure:(GCDAsyncSocket *)sock

之后调用套接字已经成功完成SSL / TLS协商。调用这个方法并不是,除非你使用startTLS提供方法。
如果SSL / TLS协商失败(无效证书等),那么该套接字将立即关闭,socketDidDisconnect:withError:委托方法将调用特定的SSL错误代码。
看到苹果的SecureTransport。h文件安全。框架为SSL错误代码的列表及其意义。

socket: didAcceptNewSocket:

- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket

当一个称为“服务器”套接字接受传入的“客户”连接。另一个套接字自动派生来处理它。
你必须保留newSocket如果你想处理的连接。否则newSocket实例将被释放,催生了连接将被关闭。
默认情况下,新的套接字将有相同的代表和delegateQueue。当然,你可以在任何时候改变这一点。
默认情况下套接字将创建自己内部的套接字队列操作。这是通过实现可配置newSocketQueueForConnectionFromAddress:onSocket:方法。

newSocketQueueForConnectionFromAddress: onSocket:

- (dispatch_queue_t)newSocketQueueForConnectionFromAddress:(NSData *)address onSocket:(GCDAsyncSocket *)sock;

套接字之前立即调用此方法:didAcceptNewSocket:。它可以允许一个监听套接字指定socketQueue新的套接字接受。如果这种方法不执行,或者返回NULL,新接受套接字将创建自己的默认队列。
既然你不能autorelease dispatch_queue,这种方法使用“新”前缀的名称来指定返回的队列被保留。
因此你会做这样的事情的实现:

return dispatch_queue_create("MyQueue", NULL);
如果你是把多个套接字在同一队列,然后应该小心增量保留每次调用该方法。
例如,您的实现可能看起来是这样的:

dispatch_retain(myExistingQueue);
return myExistingQueue;
socketDidCloseReadStream:

- (void)socketDidCloseReadStream:(GCDAsyncSocket *)sock

有条件地称为如果读流关闭,但写流可能仍然是可写的。
这只是调用委托方法如果autoDisconnectOnClosedReadStream一直没有。有关更多信息,请参见讨论autoDisconnectOnClosedReadStream方法。

socketDidDisconnect: withError:

- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)error

当一个socket断开有或没有错误。
如果你调用断开方法,和套接字不是已经断开,这代表断开方法返回之前方法将被调用。(因为断开方法是同步的)。

初始化

GCDAsyncSocket使用标准委托范式,但执行所有代表回调函数在给定的委托调度队列。这允许最大并发性,同时提供简单的线程安全。
  必须设置一个委托和委托调度队列之前使用套接字,或者你会得到一个错误。
  套接字队列的调度队列GCDAsyncSocket实例内部操作。你可以选择设置在初始化套接字队列。如果你选择不去,或者通过NULL,GCDAsyncSocket将自动创建它自己的套接字队列。如果您选择提供一个套接字队列,套接字队列不能并发队列。
  代表队列和队列可以是相同的套接字。

init

- (id)init

initWithSocketQueue:

- (id)initWithSocketQueue:(dispatch_queue_t)sq

与给定socketQueue调用指定的初始化程序。您将需要设置委托和delegateQueue之前使用套接字。

initWithDelegate: delegateQueue:

- (id)initWithDelegate:(id)aDelegate delegateQueue:(dispatch_queue_t)dq

调用指定的初始化程序给定的代表和delegateQueue。

initWithDelegate: delegateQueue: socketQueue:

- (id)initWithDelegate:(id)aDelegate delegateQueue:(dispatch_queue_t)dq socketQueue:(dispatch_queue_t)sq

指定的初始化程序。
  初始化套接字与给定的代表和代表调度队列。
  套接字发送队列是可选的。这是内部调度队列套接字操作。如果是NULL,自动将会创建一个新的调度队列。如果您选择提供一个套接字队列,套接字队列不能并发队列。
  代表队列和队列可以是相同的套接字。


配置

delegate

- (id)delegate

setDelegate:

- (void)setDelegate:(id)delegate

设置套接字的代表。
建议您nilify套接字的委托之前释放套接字。有关更多信息,请参见断开连接的方法。

delegateQueue

- (dispatch_queue_t)delegateQueue

返回delegateQueue当前设置套接字。所有委托方法将调用异步队列。

setDelegateQueue:

- (void)setDelegateQueue:(dispatch_queue_t)delegateQueue

getDelegate: delegateQueue:

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

The delegate and delegateQueue often go hand-in-hand. This method provides a thread-safe way to get the current delegate configuration (both the delegate and its queue) in one operation.

setDelegate: delegateQueue:

- (void)setDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue

提供了一种简便的和线程安全的方式改变代表和delegateQueue在一个操作。
如果你打算改变代表和delegateQueue,这种方法的首选方法。

setAutoDisconnectOnClosedReadStream:

- (void)setAutoDisconnectOnClosedReadStream:(BOOL)flag

设置autoDisconnectOnClosedReadStream配置选项。看到上面的讨论autoDisconnectOnClosedReadStream方法。

- (BOOL)isIPv4Enabled

默认情况下,IPv4和IPv6都启用。

- (void)setIPv4Enabled:(BOOL)flag

启用或禁用支持IPv4。
注意:这个属性变化已经连接的套接字或接受不影响当前的套接字的连接。这只会影响未来的连接(当前插座断开连接后)。一旦设置,偏好会影响未来所有GCDAsyncSocket实例连接。

- (BOOL)isIPv6Enabled

默认情况下,IPv4和IPv6都启用。

- (void)setIPv6Enabled:(BOOL)flag

注意:这个属性变化已经连接的套接字或接受不影响当前的套接字的连接。这只会影响未来的连接(当前插座断开连接后)。一旦设置,偏好会影响未来所有GCDAsyncSocket实例连接。

- (BOOL)isIPv4PreferredOverIPv6

默认情况下,首选协议IPv4。

- (void)setPreferIPv4OverIPv6:(BOOL)flag


接受
  
  一旦接受或连接方法之一,GCDAsyncSocket实例锁定在和其他接受/连接方法被称为不能没有首先切断socket。
  
  当传入的连接被接受,GCDAsyncSocket调用以下委托方法(按时间顺序):
  
  newSocketQueueForConnectionFromAddress:onSocket:
  socket:didAcceptNewSocket:
  
  您的服务器代码需要保留接受套接字(如果你想接受它)。否则新接受套接字将被收回委托方法返回后不久(在此期间socketDidDisconnect:withError:)

- (BOOL)acceptOnPort:(UInt16)port error:(NSError **)errPtr

讲述了套接字开始倾听和接受给定端口上的连接。当一个连接被接受,GCDAsyncSocket将催生了新实例来处理它,和套接字:didAcceptNewSocket:委托方法将被调用。
套接字将侦听所有可用的接口(例如,wifi、以太网等)。
该方法返回是的如果套接字可以开始听。如果发生错误,那么该方法将返回没有和设置可选errPtr变量。一个错误的一个例子可能是,没有代表,或已经接受套接字连接。
- (BOOL)acceptOnInterface:(NSString *)interface port:(UInt16)port error:(NSError **)errPtr


连接
  
  一旦接受或连接方法之一,GCDAsyncSocket实例锁定在和其他接受/连接方法被称为不能没有首先切断socket。

connectToHost: onPort: error:

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

连接到给定的主机和端口。
该方法调用connectToHost:onPort:viaInterface:withTimeout:error:使用默认的接口,不超时。
是的如果返回异步连接尝试开始。不返回任何如果一个错误被发现请求和设置可选errPtr变量。

connectToHost: onPort: withTimeout: error:

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

连接到给定的主机和端口和一个可选的超时。
该方法调用connectToHost:onPort:viaInterface:withTimeout:错误:使用默认界面。

connectToHost: onPort: viaInterface: withTimeout: error:

- (BOOL)connectToHost:(NSString *)host
               onPort:(UInt16)port
         viaInterface:(NSString *)interface
          withTimeout:(NSTimeInterval)timeout
                error:(NSError **)errPtr
连接到给定的主机和端口,通过可选的界面,一个可选的超时。
主机可能是一个域名(如。“deusty.com”)或(如IP地址字符串。期间”“192.168.0.2)。(如界面可能是一个名称。“en1”或“lo0”)或相应的IP地址(例如。“192.168.4.35”)

没有时间使用负的时间间隔。
这个方法将返回没有如果检测到一个错误,并设置错误指针(如果有)。可能的错误将是一个零主机,无效的接口,或套接字已经连接。
如果检测到任何错误,该方法将开始一个后台连接操作,并立即返回是的。委托回调用于通知你当套接字连接,或如果主机是不可到达的。



  读方法不会阻止(异步)。当阅读完整的套接字:didReadData:withTag:委托方法被调用。
  你可以选择任何读操作设置一个超时。(不要超时,使用消极的时间间隔)。如果一个读操作超时,相应的“插座:shouldTimeoutReadWithTag…“委托方法选择允许您扩展超时。在一个超时“socketDidDisconnect:withError:”方法被调用。

标签是为了方便。读操作的标记传递给标记传递回到您的套接字:didReadData:withTag:代表回调。您可以使用它作为一个国家id数组索引,部件号码,指针等。
 您可以调用多个连续读取方法。读取将请求排队秩序,将列中移除并连续执行。

readDataWithTimeout: tag:

- (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag

读取第一个可用的字节,可用插座。
如果超时时间值是负的,读操作不会使用超时。如果超时为零,读操作将超时如果不立即可用的套接字数据读操作列中移除。
标签是为了方便。读操作的标记传递给标记传递回到您的套接字:didReadData:withTag:代表回调。

readDataWithTimeout: buffer: bufferOffset: tag:

- (void)readDataWithTimeout:(NSTimeInterval)timeout
                     buffer:(NSMutableData *)buffer
               bufferOffset:(NSUInteger)offset
                        tag:(long)tag;
读取第一个可用的字节,可用socket。字节将附加到给定的字节缓冲区从给定的偏移量。给定的缓冲区大小会自动增加。
如果超时时间值是负的,读操作不会使用超时。如果超时为零,读操作将超时如果不立即可用的套接字数据读操作列中移除。

readDataWithTimeout: buffer: bufferOffset: maxLength: tag:

- (void)readDataWithTimeout:(NSTimeInterval)timeout
                     buffer:(NSMutableData *)buffer
               bufferOffset:(NSUInteger)offset
                  maxLength:(NSUInteger)length
                        tag:(long)tag;
读取第一个可用的字节,可用插座。字节将附加到给定的字节缓冲区从给定的偏移量。给定的缓冲区大小会自动增加。最大长度字节的读。
如果超时时间值是负的,读操作不会使用超时。如果超时为零,读操作将超时如果不立即可用的套接字数据读操作列中移除。
如果缓冲区零,套接字将自动管理缓冲区。如果最大长度为零,没有长度限制执行。

如果bufferOffset大于给定的缓冲区的长度,该方法将什么也不做,代表将不会被调用。
如果你通过一个缓冲区,你不能以任何方式改变它而GCDAsyncSocket是使用它。完成后,返回的数据在套接字:didReadData:withTag:将给定缓冲区的一个子集。也就是说,它将引用添加到给定的字节缓冲区。
标签是为了方便。读操作的标记传递给标记传递回到你onSocket:didReadData:withTag:代表回调

readDataToLength: withTimeout: tag:

- (void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag

读取的字节数。
如果超时时间值是负的,读操作不会使用超时。如果超时是零,读操作超时如果足够的数据不会立即在当时的套接字读取操作列中移除。
如果长度为0,并没有和委托不调用此方法。
标签是为了方便。读操作的标记传递给标记传递回到你onSocket:didReadData:withTag:代表回调。

readDataToLength: withTimeout: buffer: bufferOffset: tag:

- (void)readDataToLength:(NSUInteger)length
             withTimeout:(NSTimeInterval)timeout
                  buffer:(NSMutableData *)buffer
            bufferOffset:(NSUInteger)offset
                     tag:(long)tag;
读取的字节数。字节将附加到给定的字节缓冲区从给定的偏移量。给定的缓冲区大小会自动增加。
如果超时时间值是负的,读操作不会使用超时。如果超时是零,读操作超时如果足够的数据不会立即在当时的套接字读取操作列中移除。
如果缓冲区零,套接字将自动管理缓冲区。
如果长度为0,并没有和委托不调用此方法。如果bufferOffset大于给定的缓冲区的长度,该方法将什么也不做,代表将不会被调用。

如果你通过一个缓冲区,你不能以任何方式改变它而GCDAsyncSocket是使用它。完成后,返回的数据在套接字:didReadData:withTag:将给定缓冲区的一个子集。也就是说,它将引用添加到给定的字节缓冲区。
标签是为了方便。读操作的标记传递给标记传递回到你onSocket:didReadData:withTag:代表回调

readDataToData: withTimeout: tag:

- (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag

读取字节,直到(并包括)传递的“数据”参数,作为分隔符。
如果超时时间值是负的,读操作不会使用超时。如果超时是零,读操作超时如果足够的数据不会立即在当时的套接字读取操作列中移除。

如果你通过零或零长度的数据“数据”参数,该方法将什么也不做,代表将不会被调用。
从套接字读取一行,使用行分隔符(例如CRLF HTTP)的“数据”参数。注意这种方法不是字符集的注意,因此如果一个分离器可以自然发生的一部分编码字符,读取会过早结束。 
readDataToData: withTimeout: buffer: bufferOffset: tag:

- (void)readDataToData:(NSData *)data
           withTimeout:(NSTimeInterval)timeout
                buffer:(NSMutableData *)buffer
          bufferOffset:(NSUInteger)offset
                   tag:(long)tag;
读取字节,直到(并包括)传递的“数据”参数,作为分隔符。字节将附加到给定的字节缓冲区从给定的偏移量。给定的缓冲区大小会自动增加。
如果超时时间值是负的,读操作不会使用超时。如果超时是零,读操作超时如果足够的数据不会立即在当时的套接字读取操作列中移除。
如果缓冲区零,将自动为您创建一个缓冲区中。
如果bufferOffset大于给定的缓冲区的长度,该方法将什么也不做,代表将不会被调用。
如果你通过一个缓冲区,你不能以任何方式改变它而GCDAsyncSocket是使用它。完成后,返回的数据在套接字:didReadData:withTag:将给定缓冲区的一个子集。也就是说,它将引用添加到给定的字节缓冲区。
标签是为了方便。读操作的标记传递给标记传递回到您的套接字:didReadData:withTag:代表回调。
从套接字读取一行,使用行分隔符(例如CRLF HTTP)的“数据”参数。注意这种方法不是字符集的注意,因此如果一个分离器可以自然发生的一部分编码字符,读取会过早结束。

readDataToData: withTimeout: maxLength: tag:

- (void)readDataToData:(NSData *)data
           withTimeout:(NSTimeInterval)timeout
             maxLength:(NSUInteger)length
                   tag:(long)tag;
读取字节,直到(并包括)传递的“数据”参数,作为分隔符。
如果超时时间值是负的,读操作不会使用超时。如果超时是零,读操作超时如果足够的数据不会立即在当时的套接字读取操作列中移除。
如果最大长度为零,没有长度限制执行。否则如果最大长度字节读没有完成阅读,它是治疗类似于一个超时GCDAsyncSocketReadMaxedOutError——关闭套接字。阅读将成功完成如果最大长度字节读取和给定的数据被发现。

如果你通过零或零长度的数据“数据”参数,该方法将什么也不做,代表将不会被调用。如果你通过一个最大长度参数小于长度的数据参数,方法将什么也不做,代表不会叫。
标签是为了方便。读操作的标记传递给标记传递回到你onSocket:didReadData:withTag:代表回调。
从套接字读取一行,使用行分隔符(例如CRLF HTTP)的“数据”参数。注意这种方法不是字符集的注意,因此如果一个分离器可以自然发生的一部分编码字符,读取会过早结束。

readDataToData: withTimeout: buffer: bufferOffset: maxLength: tag:

- (void)readDataToData:(NSData *)data
           withTimeout:(NSTimeInterval)timeout
                buffer:(NSMutableData *)buffer
          bufferOffset:(NSUInteger)offset
             maxLength:(NSUInteger)length
                   tag:(long)tag;
读取字节,直到(并包括)传递的“数据”参数,作为分隔符。字节将附加到给定的字节缓冲区从给定的偏移量。给定的缓冲区大小会自动增加。最大长度字节的读。
如果超时时间值是负的,读操作不会使用超时。如果超时是零,读操作超时如果足够的数据不会立即在当时的套接字读取操作列中移除。
如果缓冲区零,将自动为您创建一个缓冲区中。

如果最大长度为零,没有长度限制执行。否则如果最大长度字节读没有完成阅读,它是治疗类似于一个超时AsyncSocketReadMaxedOutError——关闭套接字。阅读将成功完成如果最大长度字节读取和给定的数据被发现。
如果你通过一个最大长度参数小于长度的数据参数,方法将什么也不做,代表不会叫。如果bufferOffset大于给定的缓冲区的长度,该方法将什么也不做,代表将不会被调用。

如果你通过一个缓冲区,你不能以任何方式改变它而GCDAsyncSocket是使用它。完成后,返回的数据在套接字:didReadData:withTag:将给定缓冲区的一个子集。也就是说,它将引用添加到给定的字节缓冲区。
标签是为了方便。读操作的标记传递给标记传递回到你onSocket:didReadData:withTag:代表回调。
从套接字读取一行,使用行分隔符(例如CRLF HTTP,见下文)的“数据”参数。注意这种方法不是字符集的注意,因此如果一个分离器可以自然发生的一部分编码字符,读取会过早结束。



写方法不会阻止(异步)。当编写完整的套接字:didWriteDataWithTag:委托方法被调用。
你可以选择设置一个超时写操作。(不要超时,使用消极的时间间隔)。如果写操作超时,相应的“插座:shouldTimeoutWriteWithTag…“委托方法选择允许您扩展超时。在一个超时“socketDidDisconnect:withError:”方法被调用。
标签是为了方便。写操作的标记传递给标记传递回到您的套接字:didWriteDataWithTag:委托回调。您可以使用它作为一个国家id数组索引,部件号码,指针等。
您可以调用多个连续写方法。写操作将请求排队秩序,将列中移除,并连续执行

writeData: withTimeout: tag:

- (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag写数据到套接字,并在完成时调用委托。
如果你通过在零或零长度数据,该方法并没有和代表将不会被调用。
果超时时间值是负的,写操作不会使用超时。如果超时为零,写操作将超时如果所有数据不能立即写入套接字当时写操作列中移除。

Diagnostics


isDisconnected

- (BOOL)isDisconnected

返回是的是否断开连接的套接字。
断开连接的套接字可以回收。也就是说,它可以再次使用连接或倾听。

connectedHost

- (NSString *)connectedHost

返回的IP地址连接(远程)主机字符串格式。
如果没有连接套接字,返回零。

connectedPort

- (UInt16)connectedPort

返回连接的端口号(远程)主机。
如果没有连接套接字,返回0;

localHost

- (NSString *)localHost

返回的IP地址的本地接口用于连接。例如,这可能是类似“192.168.0.4”。
如果没有连接套接字,返回零

connectedAddress

- (NSData *)connectedAddress

返回的地址(远程)主机连接。这是一个“struct sockaddr”值裹着NSData对象。如果插座IPv4,数据将“结构指向sockaddr_in”类型的。如果插座IPv6,数据将“struct sockaddr_in6”类型的。
如果没有连接套接字,返回零。

localAddress

- (NSData *)localAddress

返回的地址用于连接的本地接口。这是一个“struct sockaddr”值裹着NSData对象。如果插座IPv4,数据将“结构指向sockaddr_in”类型的。如果插座IPv6,数据将“struct sockaddr_in6”类型的。
如果没有连接套接字,返回零。

断开

disconnect

- (void)disconnect

请注意推荐的方式释放GCDAsyncSocket实例(例如在dealloc方法)

[asyncSocket setDelegate:nil delegateQueue:NULL];
[asyncSocket disconnect];
[asyncSocket release];
disconnectAfterReading

- (void)disconnectAfterReading

所有未决读取完成后断开连接。这种方法是异步的,立即返回(即使没有等待读取)。
调用该方法之后,读写方法将什么也不做。套接字将断开即使仍有未决写道。

disconnectAfterWriting

- (void)disconnectAfterWriting

断开毕竟等待写操作完成。这种方法是异步的,立即返回(即使没有等待写操作)。
调用该方法之后,读写方法将什么也不做。套接字将断开即使还有等待读取。

disconnectAfterReadingAndWriting

- (void)disconnectAfterReadingAndWriting

所有未决读写完成后断开连接。这种方法是异步的,立即返回(即使没有等待读或写)。
电话后,读写方法将什么也不做。


Security


startTLS:

- (void)startTLS:(NSDictionary *)tlsSettings

确保使用SSL / TLS连接。
  
  调用这个方法可能在任何时候,SSL / TLS握手会发生后所有未决的读和写是完成了。仙桃许发送协议依赖StartTLS消息的选项之一,和排队同时TLS的升级,而不必等待编写完成。任何读或写计划后调用此方法将发生在固定连接。
  
  可能的TLS的设置键和值都记录在案。一些可能的密钥:

  • kCFStreamSSLLevel
  • kCFStreamSSLAllowsExpiredCertificates
  • kCFStreamSSLAllowsExpiredRoots
  • kCFStreamSSLAllowsAnyRoot
  • kCFStreamSSLValidatesCertificateChain
  • kCFStreamSSLPeerName
  • kCFStreamSSLCertificates
  • kCFStreamSSLIsServer

Advanced


performBlock:

- (void)performBlock:(dispatch_block_t)block

Utilities


hostFromAddress:

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

portFromAddress:

+ (UInt16)portFromAddress:(NSData *)address

getHost: port: fromAddress:

+ (BOOL)getHost:(NSString **)hostPtr port:(UInt16 *)portPtr fromAddress:(NSData *)address

CRLFData

Carriage-Return, Line-Feed. (0x0D0A)

+ (NSData *)CRLFData

A common line separator, for use with the readDataToData:... methods.


CRData

+ (NSData *)CRData

Carriage-Return. (0x0D)

A common line separator, for use with the readDataToData:... methods.


LFData

+ (NSData *)LFData

Line-Feed. (0x0A)

A common line separator, for use with the readDataToData:... methods.


ZeroData

+ (NSData *)ZeroData

Zero Byte. Also known as a Null Byte or Null Character (at the end of a string). (0x00)

A common line separator, for use with the readDataToData:... methods.


 类似资料:

相关阅读

相关文章

相关问答