關(guān)于Asyncsocket

iPhone的標(biāo)準(zhǔn)推薦是CFNetwork 庫編程谦絮,其封裝好的開源庫是 cocoa AsyncSocket庫两嘴,用它來簡化CFNetwork的調(diào)用翰苫,它提供了異步操作
主要特性有:
隊(duì)列的非阻塞的讀和寫菩咨,而且可選超時(shí)俱箱。你可以調(diào)用它讀取和寫入,它會(huì)當(dāng)完成后告知你
自動(dòng)的socket接收些椒。如果你調(diào)用它接收連接播瞳,它將為每個(gè)連接啟動(dòng)新的實(shí)例,當(dāng)然免糕,也可以立即關(guān)閉這些連接
委托(delegate)支持赢乓。錯(cuò)誤忧侧、連接、接收骏全、完整的讀取苍柏、完整的寫入、進(jìn)度以及斷開連接姜贡,都可以通過委托模式調(diào)用
基于run loop的试吁,而不是線程的。雖然可以在主線程或者工作線程中使用它楼咳,但你不需要這樣做熄捍。它異步的調(diào)用委托方法,使用NSRunLoop母怜。委托方法包括socket的參數(shù)余耽,可讓你在多個(gè)實(shí)例中區(qū)分
自包含在一個(gè)類中。你無需操作流或者socket苹熏,這個(gè)類幫你做了全部
支持基于IPV4和IPV6的TCP流

  加入:AsynSocket.h .m與AsynUdpSocket.h .m四個(gè)文件 及CFNetwork.framework
 TCP客戶端 
       #import "AsyncSocket.h"

       @interface HelloiPhoneViewController : UIViewController {
            UITextField    * textField;
            AsyncSocket * asyncSocket;
         }
        @property (retain, nonatomic) IBOutlet UITextField *textField;
         - (IBAction) buttonPressed: (id)sender;
         - (IBAction) textFieldDoneEditing: (id)sender;    
         @end

         在需要聯(lián)接地方使用connectToHost聯(lián)接服務(wù)器
          其中initWithDelegate的參數(shù)中self是必須碟贾。這個(gè)對(duì)象指針中的各個(gè)Socket響應(yīng)的函數(shù)將被ASyncSocket所調(diào)用.initWithDelegate把將當(dāng)前對(duì)象傳遞進(jìn)去,這樣只要在當(dāng)前對(duì)象方法實(shí)現(xiàn)相應(yīng)方法

           asyncSocket = [[AsyncSocket alloc] initWithDelegate:self]; 
           NSError *err = nil; 
           if(![asyncSocket connectToHost:host on:port error:&err]) 
            { 
               NSLog(@"Error: %@", err); 
             } 

         關(guān)于NSData對(duì)象
          無論SOCKET收發(fā)都采用NSData對(duì)象.它的定義是 http://developer.apple.com/library/mac /#documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/Reference/Reference.html
          NSData主要是帶一個(gè)(id)data指向的數(shù)據(jù)空間和長度 length.
          NSString 轉(zhuǎn)換成NSData 對(duì)象

           NSData* xmlData = [@"testdata" dataUsingEncoding:NSUTF8StringEncoding];
          NSData 轉(zhuǎn)換成NSString對(duì)象

         NSData * data;
           NSString *result = [[NSString alloc] initWithData:data         encoding:NSUTF8StringEncoding];

           發(fā)送數(shù)據(jù)
            AsyncSocket  writeData    方法來發(fā)送數(shù)據(jù)轨域,它有如下定義
- (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;

           以下是一個(gè)實(shí)例語句.
           NSData* aData= [@"test data" dataUsingEncoding: NSUTF8StringEncoding];
          [sock writeData:aData withTimeout:-1 tag:1];

          在onSocket重載函數(shù)袱耽,有如定義采用是專門用來處理SOCKET的發(fā)送數(shù)據(jù)的:
           -(void)onSocket(AsyncSocket *)sock didWriteDataWithTag:(long)tag
          {
                NSLog(@"thread(%),onSocket:%p didWriteDataWithTag:%d",[[NSThread currentThread] name],
 sock,tag);
           } 

           接收Socket數(shù)據(jù).
           在onSocket重載函數(shù),有如定義采用是專門用來處理SOCKET的接收數(shù)據(jù)的.
           -(void) onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
           在中間將其轉(zhuǎn)換成NSString進(jìn)行顯示.
NSString* aStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
NSLog(@"===%@",aStr); 
[aStr release];

  6干发、TCP連接讀取制定長度的數(shù)據(jù)
       socket連接朱巨,可能會(huì)讀取固定長度的字節(jié)
       [socket readDataToLength: withTimeout :tag]

各方法的解析
-(void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
發(fā)生錯(cuò)誤,socket關(guān)閉枉长,可以在call-back過程調(diào)用"unreadData"去取得socket的最后的數(shù)據(jù)字節(jié)冀续,當(dāng)連接的時(shí)候,該委托方法在 onSocket:didAcceptNewSocket: 或者 onSocket:didConnectToHost: 之前調(diào)用

  -(void)onSocketDidDisconnect:(ASyncSocket *)sock;
  當(dāng)socket由于或沒有錯(cuò)誤而斷開連接必峰,如果你想要在斷開連接后release socket洪唐,在此方法工作,而在onSocket:willDisconnectWithError 釋放則不安全

   -(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket;
    當(dāng)產(chǎn)生一個(gè)socket去處理連接時(shí)調(diào)用自点,此方法會(huì)返回 線程上的run-loop 的新的socket和其應(yīng)處理的委托桐罕,如果省略,則使用[NSRunLoop cunrrentRunLoop]

      -(BOOL)onSocketWillConnect:(AsyncSocket *)sock;

   -(void)onSocket:(AsyncSocket *)sock didConnectToHost :(NSString *)host port:(UINt16)port;
      當(dāng)socket連接正準(zhǔn)備讀和寫的時(shí)候調(diào)用桂敛,host屬性是一個(gè)IP地址,而不是一個(gè)DNS 名稱

     -(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long) tag;
     當(dāng)socket已完成所要求的數(shù)據(jù)讀入內(nèi)存時(shí)調(diào)用溅潜,如果有錯(cuò)誤則不調(diào)用

     -(void)onSocket:(Asyncsocket *)sock didReadPartialDataOfLength:(NSUInteger)partiaLength tag:(long)tag;
       當(dāng)一個(gè)socket讀取數(shù)據(jù)术唬,但尚未完成讀操作的時(shí)候調(diào)用,如果使用 readToData: or readToLength: 方法 會(huì)發(fā)生,可以被用來更新進(jìn)度條等東西

        -(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
         當(dāng)一個(gè)socket已完成請(qǐng)求數(shù)據(jù)的寫入時(shí)候調(diào)用

        -(void)onSocket:(AsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag;
         當(dāng)一個(gè)socket寫入一些數(shù)據(jù)滚澜,但還沒有完成整個(gè)寫入時(shí)調(diào)用粗仓,它可以用來更新進(jìn)度條等東西

           -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag elapsed:(NSTimeInterval)exapsed bytesDone:(NSUInteger)length
          使用讀操作已超時(shí)但還沒完成時(shí)調(diào)用,此方法允許隨意延遲超時(shí),如果返回一個(gè)正的時(shí)間間隔借浊,讀取的超時(shí)將有一定量的擴(kuò)展塘淑,如果不實(shí)現(xiàn)這個(gè)方法,或會(huì)像往常一樣返回一個(gè)負(fù)的時(shí)間間隔蚂斤,elapsed參數(shù)是  原超時(shí)的總和存捺,加上先前通過這種方法添加的任何補(bǔ)充, length參數(shù)是 讀操作到目前為止已讀取的字節(jié)數(shù)曙蒸, 注意捌治,如果返回正數(shù)的話,這個(gè)方法可能被一個(gè)單獨(dú)的讀取多次調(diào)用

           -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutWriteWithTag:(long)tag elapsed:(NSTimeInterval)elapsed bytesDone:(NSUInteger)length;
            如果一個(gè)寫操作已達(dá)到其超時(shí)但還沒完成時(shí)調(diào)用纽窟,同上

           -(void)onSocketDidSecure:(AsyncSocket *)sock;
           在socket成功完成ssl/tls協(xié)商時(shí)調(diào)用肖油,此方法除非你使用提供startTLS方法時(shí)候才調(diào)用,
如果ssl/tls是無效的證書臂港,socket將會(huì)立即關(guān)閉森枪,onSocket:willDisconnectWithError:代理方法竟會(huì)與特定的ssl錯(cuò)誤代碼一起調(diào)用

           -(BOOL)canSafelySetDelegate
           用來查看在改變它之前,是否帶有與當(dāng)前的委托有懸而未決的業(yè)務(wù)(讀/寫)审孽。當(dāng)然县袱,應(yīng)在安全連接或接受委托之前改變委托

          一旦接收或連接方法之一被調(diào)用,AsyncSocket實(shí)例會(huì)被鎖定瓷胧,其他接收/連接方法在沒有先斷開socket不會(huì)被調(diào)用
          如果嘗試失敗或超時(shí)显拳,這些方法要么返回NO 要么調(diào)用 onSocket:willDisconnectWithError: 或 onSockedDidDisconnect
          當(dāng)傳入的連接被接受,AsyncSocket調(diào)用多個(gè)委托方法搓萧。這些方法按照時(shí)間順序排列:
             1.onSocket:didAcceptNewSocket:
             2.onSocket:wantsRunLoopForNewSocket:
             3. onSocketWillConnect:
           
          你的服務(wù)器的代碼將需要保留公認(rèn)的socket(如果要接受它)杂数,最好的地方是要做到這一點(diǎn)可能在onSocket:didAcceptNewSocket:方法    
         在讀和寫流已經(jīng)為新接受的socket設(shè)置,onSocket:didConnectToHost:port 方法將在適當(dāng)?shù)倪\(yùn)行循環(huán)調(diào)用
         多線程注意瘸洛,如果要想通過實(shí)施onSocket:wantsRunLoopForNewSocket:揍移,移動(dòng)另一個(gè)新接受的socket去到另一個(gè)循環(huán)的socket。然后反肋,應(yīng)該在調(diào)用讀和寫或者startTLS方法前那伐,等待直到onSocket:didConnectToHost:port:方法。否則讀和寫時(shí)間原定于不正確的runloop石蔗,混亂可能會(huì)隨之而來


         -(BOOL)acceptOnPort:(UInit16)port error:(NSError **)errPtr;
         告訴socket開始聽取和接受制定端口上的連接罕邀,當(dāng)一個(gè)連接到來的時(shí)候,AsyncSocket實(shí)例將調(diào)用各種委托方法养距,socket將聽取所有可用的接口(wifi,以太網(wǎng)等)

         -(BOOL)connectToHost:(NSString *)hostname onPort:(UInt16)port error :(NSError **)errPtr;
         連接給定的主機(jī)和端口诉探,主機(jī)hostname可以是域名或者是Ip地址

         -(BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError *)errPtr;
         連接到一個(gè)給定的地址,制定一個(gè)sockaddr結(jié)構(gòu)包裹住一個(gè)NSData對(duì)象,例如棍厌,NSData對(duì)象從NSNetService的地址方法返回,如果有一個(gè)現(xiàn)有的sockaddr結(jié)構(gòu)肾胯,可以將它轉(zhuǎn)換到一個(gè)NSData對(duì)象竖席,像這樣:

struct sockaddr sa -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len];
struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len];

         -(void)disconnect;
            立即斷開,任何未處理的讀或?qū)懚紝⒈粊G棄
            如果socket還沒有斷開敬肚,在這個(gè)方法返回之前毕荐,onSocketDidDisconnect 委托方法將會(huì)被立即調(diào)用
             注意推薦釋放AsyncSocket實(shí)例的方式:
               [asyncSocket setDelegate:nil];
               [asyncSocket disconnect];
               [asyncSocket release];

          -(void)disconnectAfterReading;
             在已經(jīng)完成了所有懸而未決的讀取時(shí) 斷開,在調(diào)用之后,讀取和寫入方法將無用,socket將斷開 即使仍有待寫入

          - (NSString *)connectedHost;
          - (UInt16)connectedPort;
          - (NSString *)localHost;
          - (UInt16)localPort;
            返回本地和遠(yuǎn)程主機(jī)和端口給連接的socket艳馒,如果沒有連接會(huì)返回nil或0,主機(jī)將會(huì)是一個(gè)IP地址

         -(NSData *)connectedAddress
         -(NSData *)localAddresss
            返回本地和遠(yuǎn)程的地址給連接的socket憎亚,指定一個(gè)socketaddr結(jié)構(gòu)包裹在一個(gè)NSData對(duì)象


            readData和writeData方法不會(huì)是block(它們是異步的)
           當(dāng)讀完成 onSocket:didReadData:withTag: 委托方法時(shí)調(diào)用
           當(dāng)寫完成 onSocket:didWriteDataWithTag: 委托方法時(shí)調(diào)用
           可以選擇任何讀/寫操作的超時(shí)設(shè)置(為了不超時(shí),使用負(fù)時(shí)間間隔鹰溜。)
           如果讀/寫操作超時(shí)虽填,相應(yīng)的 onSocket:shouldTimeout...委托方法被調(diào)用去選擇性地允許我們?nèi)パ娱L超時(shí)
           超時(shí)后,onSocket:willDisconnectWithError: 方法被調(diào)用,緊接著是 onSocketDidDisconnect
           tag是為了方便曹动,可以使用它作為數(shù)組的索引斋日、步數(shù)、state id 墓陈、指針等 



        -(void)readDataWithTimeout:(NSTimeInterval)tiemout tag:(long)tag;
          讀取socket上第一次成為可用的字節(jié),如果timeout值是負(fù)數(shù)的恶守,讀操作將不使用timeout

        - (void)readDataWithTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInterger)offset tag:(long)tag;
          讀取socket上第一次成為可用的字節(jié)
          字節(jié)將被追加到給定的字節(jié)緩沖區(qū),從給定的偏移量開始
          如果需要贡必,給定的緩沖區(qū)大小將會(huì)自動(dòng)增加
          如果timeout值是負(fù)數(shù)的兔港,讀操作將不使用timeout
          如果緩沖區(qū)為空,socket會(huì)為我們創(chuàng)建一個(gè)緩沖區(qū)
          如果bufferOffset是大于給定的緩沖區(qū)的長度仔拟,該方法將無用衫樊,委托將不會(huì)被調(diào)用
          如果你傳遞一個(gè)緩沖區(qū),當(dāng)AsyncSocket在使用它的時(shí)候你不能以任何方式改變它
          完成之后利花,onSocket:didReadData:withTag 返回的數(shù)據(jù)將是一個(gè)給定的緩沖區(qū)的子集
          也就是說科侈,它將會(huì)被引用到被追加的給定的緩沖區(qū)的字節(jié)

        -(void)readDataToLength:(NSUInterger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;
        讀取給定的字節(jié)數(shù),如果length為0炒事,方法將無用臀栈,委托將不會(huì)被調(diào)用

        -(void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)tiemout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
        讀取給定的字節(jié)數(shù),在給定的偏移開始,字節(jié)將被追加到給定的字節(jié)緩沖區(qū)

        -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
        讀取字節(jié)直到(包括)傳入的作為分隔的"data"參數(shù)
        如果傳遞0或者0長度的數(shù)據(jù)挠乳,"data"參數(shù)权薯,該方法將無用,委托將不會(huì)被調(diào)用
        從socket讀取一行睡扬,使用"data"參數(shù)作為行的分隔符 (如HTTP的CRLF)
        注意盟蚣,此方法不是字符集,因此卖怜,如果一個(gè)分隔符出現(xiàn)刁俭,它自然可以作為進(jìn)行編碼的一部分,讀取將提前結(jié)束

        -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
       讀取字節(jié)直到(包括)傳入的作為分隔的“data”參數(shù)韧涨,在給定的偏移量開始牍戚,字節(jié)將被追加到給定的字節(jié)緩沖區(qū)。
       從socket讀取一行虑粥,使用"data"參數(shù)作為行的分隔符(如HTTP的CRLF)

       -(void)writeData:(NSData *)data withTimeout:(NSTimeInterval) timeout tag:(long)tag;
      將data寫入socket如孝,當(dāng)完成的時(shí)候委托被調(diào)用 

       - (float)progressOfReadReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
       - (float)progressOfWriteReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
       返回當(dāng)前讀或?qū)懙倪M(jìn)度,從0.0 到 1.0 或者 如果沒有讀/寫的時(shí)候返回Nan(使用isNan來檢查)

tag娩贷、done第晰、total如果不為空的話,它們將會(huì)被填補(bǔ)

       - (void)startTLS:(NSDictionary *)tlsSettings;
       確保使用ssl/tls連接
       這方法可被隨時(shí)調(diào)用彬祖,tls握手將會(huì)發(fā)生在所有懸而未決的讀/寫完成之后茁瘦。這緊跟著一個(gè)發(fā)送依賴 StartTLS消息的協(xié)議選項(xiàng),在排隊(duì)升級(jí)到TLS的同一時(shí)間储笑,而不必等待寫入完成甜熔。在這個(gè)方法被調(diào)用后,任何讀寫計(jì)劃 將會(huì)發(fā)生在安全鏈接
       對(duì)于可能的keys和TLS設(shè)置的值是有據(jù)可查的
       一些可能的keys是:
          * - kCFStreamSSLLevel
          * - kCFStreamSSLAllowsExpiredCertificates
          * - kCFStreamSSLAllowsExpiredRoots
          * - kCFStreamSSLAllowsAnyRoot
          * - kCFStreamSSLValidatesCertificateChain
          * - kCFStreamSSLPeerName
          * - kCFStreamSSLCertificates
          * - kCFStreamSSLIsServer

       如果你傳遞空或者空字典,將使用默認(rèn)的字典
       默認(rèn)設(shè)置將檢查以確保由簽署可信的第三方證書機(jī)構(gòu)和沒有過期的遠(yuǎn)程連接的證書
       然而突倍,它不會(huì)驗(yàn)證證書上的名字腔稀,除非你給它一個(gè)名字,通過kCFStreamSSLPeerName鍵去驗(yàn)證
       這對(duì)安全的影響是重要的理解
       想象一下你正試圖創(chuàng)建一個(gè)到MySecureServer.com的安全連接羽历,但因?yàn)橐粋€(gè)被攻擊的DNS服務(wù)器焊虏,所以你的socket被定向到MaliciousServer.com
       如果你只是使用默認(rèn)設(shè)置,MaliciousServer.com 有一個(gè)有效的證書
       默認(rèn)設(shè)置將無法監(jiān)測(cè)到任何問題秕磷,因?yàn)樽C書是有效的
      在這個(gè)特殊的情況下诵闭,要妥善保護(hù)你的連接,應(yīng)設(shè)置kCFStreamSSLPeerName性質(zhì)為MySecureServer.com.
     如果事前你不知道對(duì)等的名字的遠(yuǎn)程主機(jī)(例如澎嚣,你不確認(rèn)它是domain.com" or "www.domain.com")疏尿,那么你可以使用默認(rèn)設(shè)置來驗(yàn)證證書,然后在獲得驗(yàn)證的發(fā)行后使用X509Certificate類來驗(yàn)證,X509Certificate類的CocoaAsyncSocket開源項(xiàng)目的一部分

     -(void)enablePrebuffering
     對(duì)于處理readDataToData請(qǐng)求币叹,數(shù)據(jù)是必須從socket以小增量的方式讀取出來的
     性能通過允許AsyncSocket去一次性讀大塊的數(shù)據(jù)和存儲(chǔ)任何一個(gè)小的內(nèi)部緩沖區(qū)溢出的東西來大大提高
     這被稱為預(yù)緩沖润歉,就好像一些數(shù)據(jù)在你要求它之前就可能被讀取出來
     如果你經(jīng)常使用readDataToData,使用預(yù)緩沖會(huì)有更好的性能颈抚,尤其是在iphone上
     默認(rèn)的預(yù)緩沖狀態(tài)是由DEFAULT_PREBUFFERING 定義控制的踩衩,強(qiáng)烈建議設(shè)置其為yes
     這方法存在一些預(yù)緩沖需要一些不可預(yù)見的原因被默認(rèn)禁用的情況,這時(shí)贩汉,這種方法存在允許當(dāng)就緒時(shí)驱富,可輕松啟用預(yù)緩沖

      -(BOOL)moveToRunLoop:(NSRunLoop *)runLoop;
      當(dāng)你創(chuàng)建一個(gè)AsyncSocket,它被添加到當(dāng)前線程runloop
      對(duì)于手動(dòng)創(chuàng)建的socket匹舞,在線程上你打算使用它褐鸥,它是最容易簡單的創(chuàng)建的線程上的socket
      當(dāng)一個(gè)新的socket被接受,委托方法 onSocket:wantsRunLoopForNewSocket 會(huì)被調(diào)用 允許你在一個(gè)單獨(dú)的線程上放置socket赐稽,這個(gè)工作最好結(jié)合在同一個(gè)線程池設(shè)計(jì)
      如果叫榕,但是浑侥,在一個(gè)單獨(dú)的線程上,在之后的時(shí)間晰绎,你需要移動(dòng)一個(gè)socket寓落,這個(gè)方法可以用來完成任務(wù)
      此方法必須從 當(dāng)前運(yùn)行的 線程/runloop 的socket 調(diào)用
      注意:此方法調(diào)用后,所有進(jìn)一步的方法應(yīng)該從給定的runloop上調(diào)用這個(gè)對(duì)象
      此外荞下,所有委托調(diào)用將會(huì)發(fā)送到給定的runloop


      - (BOOL)setRunLoopModes:(NSArray *)runLoopModes;
      - (BOOL)addRunLoopMode:(NSString *)runLoopMode;
      - (BOOL)removeRunLoopMode:(NSString *)runLoopMode;
       允許你配置 socket 使用的 運(yùn)行循環(huán)模式
       運(yùn)行循環(huán)模式設(shè)置默認(rèn)是NSRunLoopCommonModes
       如果你想你的socket 在其他模式下繼續(xù)操作伶选,你可能需要添加模式 NSModalPanelRunLoopMode 或者 NSEventTrackingRunLoopMode ,或者你可能只想使用 NSRunLoopCommonModes
       可接受的socket將自動(dòng) 繼承相同的運(yùn)行循環(huán)模式就像偵聽socket
       注意:NSRunLoopCommonModes 定義在10.5,對(duì)于之前的版本可使用 kCFRunLoopCommonModes

      -(NSArray *)runLoopModes
        返回當(dāng)前正在運(yùn)行的循環(huán)模式的AsyncSocket實(shí)例尖昏, run loop modes的默認(rèn)設(shè)置是NSDefaultRunLoopMode

      -(NSData *)unreadData;
     一個(gè)錯(cuò)誤的事件仰税,在 onSocket:willDisconnectWithError: 將會(huì)被調(diào)用 去讀取留在socket上的任何數(shù)據(jù)

      + (NSData *)CRLFData;   // 0x0D0A

各方法的解析
-(void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
發(fā)生錯(cuò)誤,socket關(guān)閉抽诉,可以在call-back過程調(diào)用"unreadData"去取得socket的最后的數(shù)據(jù)字節(jié)陨簇,當(dāng)連接的時(shí)候,該委托方法在 onSocket:didAcceptNewSocket: 或者 onSocket:didConnectToHost: 之前調(diào)用

  -(void)onSocketDidDisconnect:(ASyncSocket *)sock;
  當(dāng)socket由于或沒有錯(cuò)誤而斷開連接掸鹅,如果你想要在斷開連接后release socket塞帐,在此方法工作,而在onSocket:willDisconnectWithError 釋放則不安全

   -(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket;
    當(dāng)產(chǎn)生一個(gè)socket去處理連接時(shí)調(diào)用巍沙,此方法會(huì)返回 線程上的run-loop 的新的socket和其應(yīng)處理的委托葵姥,如果省略,則使用[NSRunLoop cunrrentRunLoop]

      -(BOOL)onSocketWillConnect:(AsyncSocket *)sock;

   -(void)onSocket:(AsyncSocket *)sock didConnectToHost :(NSString *)host port:(UINt16)port;
      當(dāng)socket連接正準(zhǔn)備讀和寫的時(shí)候調(diào)用句携,host屬性是一個(gè)IP地址榔幸,而不是一個(gè)DNS 名稱

     -(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long) tag;
     當(dāng)socket已完成所要求的數(shù)據(jù)讀入內(nèi)存時(shí)調(diào)用,如果有錯(cuò)誤則不調(diào)用

     -(void)onSocket:(Asyncsocket *)sock didReadPartialDataOfLength:(NSUInteger)partiaLength tag:(long)tag;
       當(dāng)一個(gè)socket讀取數(shù)據(jù)矮嫉,但尚未完成讀操作的時(shí)候調(diào)用削咆,如果使用 readToData: or readToLength: 方法 會(huì)發(fā)生,可以被用來更新進(jìn)度條等東西

        -(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
         當(dāng)一個(gè)socket已完成請(qǐng)求數(shù)據(jù)的寫入時(shí)候調(diào)用

        -(void)onSocket:(AsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag;
         當(dāng)一個(gè)socket寫入一些數(shù)據(jù),但還沒有完成整個(gè)寫入時(shí)調(diào)用蠢笋,它可以用來更新進(jìn)度條等東西

           -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag elapsed:(NSTimeInterval)exapsed bytesDone:(NSUInteger)length
          使用讀操作已超時(shí)但還沒完成時(shí)調(diào)用拨齐,此方法允許隨意延遲超時(shí),如果返回一個(gè)正的時(shí)間間隔昨寞,讀取的超時(shí)將有一定量的擴(kuò)展瞻惋,如果不實(shí)現(xiàn)這個(gè)方法,或會(huì)像往常一樣返回一個(gè)負(fù)的時(shí)間間隔援岩,elapsed參數(shù)是  原超時(shí)的總和歼狼,加上先前通過這種方法添加的任何補(bǔ)充, length參數(shù)是 讀操作到目前為止已讀取的字節(jié)數(shù)享怀, 注意羽峰,如果返回正數(shù)的話,這個(gè)方法可能被一個(gè)單獨(dú)的讀取多次調(diào)用

           -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutWriteWithTag:(long)tag elapsed:(NSTimeInterval)elapsed bytesDone:(NSUInteger)length;
            如果一個(gè)寫操作已達(dá)到其超時(shí)但還沒完成時(shí)調(diào)用,同上

           -(void)onSocketDidSecure:(AsyncSocket *)sock;
           在socket成功完成ssl/tls協(xié)商時(shí)調(diào)用梅屉,此方法除非你使用提供startTLS方法時(shí)候才調(diào)用值纱,
如果ssl/tls是無效的證書,socket將會(huì)立即關(guān)閉履植,onSocket:willDisconnectWithError:代理方法竟會(huì)與特定的ssl錯(cuò)誤代碼一起調(diào)用

           -(BOOL)canSafelySetDelegate
           用來查看在改變它之前计雌,是否帶有與當(dāng)前的委托有懸而未決的業(yè)務(wù)(讀/寫)。當(dāng)然玫霎,應(yīng)在安全連接或接受委托之前改變委托

          一旦接收或連接方法之一被調(diào)用,AsyncSocket實(shí)例會(huì)被鎖定妈橄,其他接收/連接方法在沒有先斷開socket不會(huì)被調(diào)用
          如果嘗試失敗或超時(shí)庶近,這些方法要么返回NO 要么調(diào)用 onSocket:willDisconnectWithError: 或 onSockedDidDisconnect
          當(dāng)傳入的連接被接受,AsyncSocket調(diào)用多個(gè)委托方法眷蚓。這些方法按照時(shí)間順序排列:
             1.onSocket:didAcceptNewSocket:
             2.onSocket:wantsRunLoopForNewSocket:
             3. onSocketWillConnect:
           
          你的服務(wù)器的代碼將需要保留公認(rèn)的socket(如果要接受它)鼻种,最好的地方是要做到這一點(diǎn)可能在onSocket:didAcceptNewSocket:方法    
         在讀和寫流已經(jīng)為新接受的socket設(shè)置,onSocket:didConnectToHost:port 方法將在適當(dāng)?shù)倪\(yùn)行循環(huán)調(diào)用
         多線程注意沙热,如果要想通過實(shí)施onSocket:wantsRunLoopForNewSocket:叉钥,移動(dòng)另一個(gè)新接受的socket去到另一個(gè)循環(huán)的socket。然后篙贸,應(yīng)該在調(diào)用讀和寫或者startTLS方法前投队,等待直到onSocket:didConnectToHost:port:方法。否則讀和寫時(shí)間原定于不正確的runloop爵川,混亂可能會(huì)隨之而來


         -(BOOL)acceptOnPort:(UInit16)port error:(NSError **)errPtr;
         告訴socket開始聽取和接受制定端口上的連接敷鸦,當(dāng)一個(gè)連接到來的時(shí)候,AsyncSocket實(shí)例將調(diào)用各種委托方法寝贡,socket將聽取所有可用的接口(wifi,以太網(wǎng)等)

         -(BOOL)connectToHost:(NSString *)hostname onPort:(UInt16)port error :(NSError **)errPtr;
         連接給定的主機(jī)和端口扒披,主機(jī)hostname可以是域名或者是Ip地址

         -(BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError *)errPtr;
         連接到一個(gè)給定的地址,制定一個(gè)sockaddr結(jié)構(gòu)包裹住一個(gè)NSData對(duì)象,例如圃泡,NSData對(duì)象從NSNetService的地址方法返回,如果有一個(gè)現(xiàn)有的sockaddr結(jié)構(gòu)碟案,可以將它轉(zhuǎn)換到一個(gè)NSData對(duì)象,像這樣:

struct sockaddr sa -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len];
struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len];

         -(void)disconnect;
            立即斷開颇蜡,任何未處理的讀或?qū)懚紝⒈粊G棄
            如果socket還沒有斷開价说,在這個(gè)方法返回之前,onSocketDidDisconnect 委托方法將會(huì)被立即調(diào)用
             注意推薦釋放AsyncSocket實(shí)例的方式:
               [asyncSocket setDelegate:nil];
               [asyncSocket disconnect];
               [asyncSocket release];

          -(void)disconnectAfterReading;
             在已經(jīng)完成了所有懸而未決的讀取時(shí) 斷開,在調(diào)用之后澡匪,讀取和寫入方法將無用,socket將斷開 即使仍有待寫入

          - (NSString *)connectedHost;
          - (UInt16)connectedPort;
          - (NSString *)localHost;
          - (UInt16)localPort;
            返回本地和遠(yuǎn)程主機(jī)和端口給連接的socket熔任,如果沒有連接會(huì)返回nil或0,主機(jī)將會(huì)是一個(gè)IP地址

         -(NSData *)connectedAddress
         -(NSData *)localAddresss
            返回本地和遠(yuǎn)程的地址給連接的socket,指定一個(gè)socketaddr結(jié)構(gòu)包裹在一個(gè)NSData對(duì)象


            readData和writeData方法不會(huì)是block(它們是異步的)
           當(dāng)讀完成 onSocket:didReadData:withTag: 委托方法時(shí)調(diào)用
           當(dāng)寫完成 onSocket:didWriteDataWithTag: 委托方法時(shí)調(diào)用
           可以選擇任何讀/寫操作的超時(shí)設(shè)置(為了不超時(shí)唁情,使用負(fù)時(shí)間間隔疑苔。)
           如果讀/寫操作超時(shí),相應(yīng)的 onSocket:shouldTimeout...委托方法被調(diào)用去選擇性地允許我們?nèi)パ娱L超時(shí)
           超時(shí)后甸鸟,onSocket:willDisconnectWithError: 方法被調(diào)用,緊接著是 onSocketDidDisconnect
           tag是為了方便惦费,可以使用它作為數(shù)組的索引兵迅、步數(shù)、state id 薪贫、指針等 



        -(void)readDataWithTimeout:(NSTimeInterval)tiemout tag:(long)tag;
          讀取socket上第一次成為可用的字節(jié),如果timeout值是負(fù)數(shù)的恍箭,讀操作將不使用timeout

        - (void)readDataWithTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInterger)offset tag:(long)tag;
          讀取socket上第一次成為可用的字節(jié)
          字節(jié)將被追加到給定的字節(jié)緩沖區(qū),從給定的偏移量開始
          如果需要瞧省,給定的緩沖區(qū)大小將會(huì)自動(dòng)增加
          如果timeout值是負(fù)數(shù)的扯夭,讀操作將不使用timeout
          如果緩沖區(qū)為空,socket會(huì)為我們創(chuàng)建一個(gè)緩沖區(qū)
          如果bufferOffset是大于給定的緩沖區(qū)的長度鞍匾,該方法將無用交洗,委托將不會(huì)被調(diào)用
          如果你傳遞一個(gè)緩沖區(qū),當(dāng)AsyncSocket在使用它的時(shí)候你不能以任何方式改變它
          完成之后橡淑,onSocket:didReadData:withTag 返回的數(shù)據(jù)將是一個(gè)給定的緩沖區(qū)的子集
          也就是說构拳,它將會(huì)被引用到被追加的給定的緩沖區(qū)的字節(jié)

        -(void)readDataToLength:(NSUInterger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;
        讀取給定的字節(jié)數(shù),如果length為0梁棠,方法將無用置森,委托將不會(huì)被調(diào)用

        -(void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)tiemout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
        讀取給定的字節(jié)數(shù),在給定的偏移開始,字節(jié)將被追加到給定的字節(jié)緩沖區(qū)

        -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
        讀取字節(jié)直到(包括)傳入的作為分隔的"data"參數(shù)
        如果傳遞0或者0長度的數(shù)據(jù)符糊,"data"參數(shù)凫海,該方法將無用,委托將不會(huì)被調(diào)用
        從socket讀取一行濒蒋,使用"data"參數(shù)作為行的分隔符 (如HTTP的CRLF)
        注意盐碱,此方法不是字符集,因此沪伙,如果一個(gè)分隔符出現(xiàn)瓮顽,它自然可以作為進(jìn)行編碼的一部分,讀取將提前結(jié)束

        -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
       讀取字節(jié)直到(包括)傳入的作為分隔的“data”參數(shù)围橡,在給定的偏移量開始暖混,字節(jié)將被追加到給定的字節(jié)緩沖區(qū)。
       從socket讀取一行翁授,使用"data"參數(shù)作為行的分隔符(如HTTP的CRLF)

       -(void)writeData:(NSData *)data withTimeout:(NSTimeInterval) timeout tag:(long)tag;
      將data寫入socket拣播,當(dāng)完成的時(shí)候委托被調(diào)用 

       - (float)progressOfReadReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
       - (float)progressOfWriteReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
       返回當(dāng)前讀或?qū)懙倪M(jìn)度,從0.0 到 1.0 或者 如果沒有讀/寫的時(shí)候返回Nan(使用isNan來檢查)

tag收擦、done贮配、total如果不為空的話轮洋,它們將會(huì)被填補(bǔ)

       - (void)startTLS:(NSDictionary *)tlsSettings;
       確保使用ssl/tls連接
       這方法可被隨時(shí)調(diào)用惋戏,tls握手將會(huì)發(fā)生在所有懸而未決的讀/寫完成之后于未。這緊跟著一個(gè)發(fā)送依賴 StartTLS消息的協(xié)議選項(xiàng),在排隊(duì)升級(jí)到TLS的同一時(shí)間兽间,而不必等待寫入完成辱士。在這個(gè)方法被調(diào)用后,任何讀寫計(jì)劃 將會(huì)發(fā)生在安全鏈接
       對(duì)于可能的keys和TLS設(shè)置的值是有據(jù)可查的
       一些可能的keys是:
          * - kCFStreamSSLLevel
          * - kCFStreamSSLAllowsExpiredCertificates
          * - kCFStreamSSLAllowsExpiredRoots
          * - kCFStreamSSLAllowsAnyRoot
          * - kCFStreamSSLValidatesCertificateChain
          * - kCFStreamSSLPeerName
          * - kCFStreamSSLCertificates
          * - kCFStreamSSLIsServer

       如果你傳遞空或者空字典玉掸,將使用默認(rèn)的字典
       默認(rèn)設(shè)置將檢查以確保由簽署可信的第三方證書機(jī)構(gòu)和沒有過期的遠(yuǎn)程連接的證書
       然而伴挚,它不會(huì)驗(yàn)證證書上的名字,除非你給它一個(gè)名字沦辙,通過kCFStreamSSLPeerName鍵去驗(yàn)證
       這對(duì)安全的影響是重要的理解
       想象一下你正試圖創(chuàng)建一個(gè)到MySecureServer.com的安全連接夫植,但因?yàn)橐粋€(gè)被攻擊的DNS服務(wù)器,所以你的socket被定向到MaliciousServer.com
       如果你只是使用默認(rèn)設(shè)置油讯,MaliciousServer.com 有一個(gè)有效的證書
       默認(rèn)設(shè)置將無法監(jiān)測(cè)到任何問題详民,因?yàn)樽C書是有效的
      在這個(gè)特殊的情況下,要妥善保護(hù)你的連接撞羽,應(yīng)設(shè)置kCFStreamSSLPeerName性質(zhì)為MySecureServer.com.
     如果事前你不知道對(duì)等的名字的遠(yuǎn)程主機(jī)(例如阐斜,你不確認(rèn)它是domain.com" or "www.domain.com"),那么你可以使用默認(rèn)設(shè)置來驗(yàn)證證書诀紊,然后在獲得驗(yàn)證的發(fā)行后使用X509Certificate類來驗(yàn)證,X509Certificate類的CocoaAsyncSocket開源項(xiàng)目的一部分

     -(void)enablePrebuffering
     對(duì)于處理readDataToData請(qǐng)求,數(shù)據(jù)是必須從socket以小增量的方式讀取出來的
     性能通過允許AsyncSocket去一次性讀大塊的數(shù)據(jù)和存儲(chǔ)任何一個(gè)小的內(nèi)部緩沖區(qū)溢出的東西來大大提高
     這被稱為預(yù)緩沖隅俘,就好像一些數(shù)據(jù)在你要求它之前就可能被讀取出來
     如果你經(jīng)常使用readDataToData邻奠,使用預(yù)緩沖會(huì)有更好的性能,尤其是在iphone上
     默認(rèn)的預(yù)緩沖狀態(tài)是由DEFAULT_PREBUFFERING 定義控制的为居,強(qiáng)烈建議設(shè)置其為yes
     這方法存在一些預(yù)緩沖需要一些不可預(yù)見的原因被默認(rèn)禁用的情況碌宴,這時(shí),這種方法存在允許當(dāng)就緒時(shí)蒙畴,可輕松啟用預(yù)緩沖

      -(BOOL)moveToRunLoop:(NSRunLoop *)runLoop;
      當(dāng)你創(chuàng)建一個(gè)AsyncSocket贰镣,它被添加到當(dāng)前線程runloop
      對(duì)于手動(dòng)創(chuàng)建的socket,在線程上你打算使用它膳凝,它是最容易簡單的創(chuàng)建的線程上的socket
      當(dāng)一個(gè)新的socket被接受碑隆,委托方法 onSocket:wantsRunLoopForNewSocket 會(huì)被調(diào)用 允許你在一個(gè)單獨(dú)的線程上放置socket,這個(gè)工作最好結(jié)合在同一個(gè)線程池設(shè)計(jì)
      如果蹬音,但是上煤,在一個(gè)單獨(dú)的線程上,在之后的時(shí)間著淆,你需要移動(dòng)一個(gè)socket劫狠,這個(gè)方法可以用來完成任務(wù)
      此方法必須從 當(dāng)前運(yùn)行的 線程/runloop 的socket 調(diào)用
      注意:此方法調(diào)用后,所有進(jìn)一步的方法應(yīng)該從給定的runloop上調(diào)用這個(gè)對(duì)象
      此外永部,所有委托調(diào)用將會(huì)發(fā)送到給定的runloop


      - (BOOL)setRunLoopModes:(NSArray *)runLoopModes;
      - (BOOL)addRunLoopMode:(NSString *)runLoopMode;
      - (BOOL)removeRunLoopMode:(NSString *)runLoopMode;
       允許你配置 socket 使用的 運(yùn)行循環(huán)模式
       運(yùn)行循環(huán)模式設(shè)置默認(rèn)是NSRunLoopCommonModes
       如果你想你的socket 在其他模式下繼續(xù)操作独泞,你可能需要添加模式 NSModalPanelRunLoopMode 或者 NSEventTrackingRunLoopMode ,或者你可能只想使用 NSRunLoopCommonModes
       可接受的socket將自動(dòng) 繼承相同的運(yùn)行循環(huán)模式就像偵聽socket
       注意:NSRunLoopCommonModes 定義在10.5,對(duì)于之前的版本可使用 kCFRunLoopCommonModes

      -(NSArray *)runLoopModes
        返回當(dāng)前正在運(yùn)行的循環(huán)模式的AsyncSocket實(shí)例苔埋, run loop modes的默認(rèn)設(shè)置是NSDefaultRunLoopMode

      -(NSData *)unreadData;
     一個(gè)錯(cuò)誤的事件懦砂,在 onSocket:willDisconnectWithError: 將會(huì)被調(diào)用 去讀取留在socket上的任何數(shù)據(jù)

      + (NSData *)CRLFData;   // 0x0D0A

各方法的解析
-(void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
發(fā)生錯(cuò)誤,socket關(guān)閉,可以在call-back過程調(diào)用"unreadData"去取得socket的最后的數(shù)據(jù)字節(jié)孕惜,當(dāng)連接的時(shí)候愧薛,該委托方法在 onSocket:didAcceptNewSocket: 或者 onSocket:didConnectToHost: 之前調(diào)用

  -(void)onSocketDidDisconnect:(ASyncSocket *)sock;
  當(dāng)socket由于或沒有錯(cuò)誤而斷開連接,如果你想要在斷開連接后release socket衫画,在此方法工作毫炉,而在onSocket:willDisconnectWithError 釋放則不安全

   -(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket;
    當(dāng)產(chǎn)生一個(gè)socket去處理連接時(shí)調(diào)用,此方法會(huì)返回 線程上的run-loop 的新的socket和其應(yīng)處理的委托削罩,如果省略瞄勾,則使用[NSRunLoop cunrrentRunLoop]

      -(BOOL)onSocketWillConnect:(AsyncSocket *)sock;

   -(void)onSocket:(AsyncSocket *)sock didConnectToHost :(NSString *)host port:(UINt16)port;
      當(dāng)socket連接正準(zhǔn)備讀和寫的時(shí)候調(diào)用,host屬性是一個(gè)IP地址弥激,而不是一個(gè)DNS 名稱

     -(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long) tag;
     當(dāng)socket已完成所要求的數(shù)據(jù)讀入內(nèi)存時(shí)調(diào)用进陡,如果有錯(cuò)誤則不調(diào)用

     -(void)onSocket:(Asyncsocket *)sock didReadPartialDataOfLength:(NSUInteger)partiaLength tag:(long)tag;
       當(dāng)一個(gè)socket讀取數(shù)據(jù),但尚未完成讀操作的時(shí)候調(diào)用微服,如果使用 readToData: or readToLength: 方法 會(huì)發(fā)生,可以被用來更新進(jìn)度條等東西

        -(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
         當(dāng)一個(gè)socket已完成請(qǐng)求數(shù)據(jù)的寫入時(shí)候調(diào)用

        -(void)onSocket:(AsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag;
         當(dāng)一個(gè)socket寫入一些數(shù)據(jù)趾疚,但還沒有完成整個(gè)寫入時(shí)調(diào)用,它可以用來更新進(jìn)度條等東西

           -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag elapsed:(NSTimeInterval)exapsed bytesDone:(NSUInteger)length
          使用讀操作已超時(shí)但還沒完成時(shí)調(diào)用以蕴,此方法允許隨意延遲超時(shí)糙麦,如果返回一個(gè)正的時(shí)間間隔,讀取的超時(shí)將有一定量的擴(kuò)展丛肮,如果不實(shí)現(xiàn)這個(gè)方法赡磅,或會(huì)像往常一樣返回一個(gè)負(fù)的時(shí)間間隔,elapsed參數(shù)是  原超時(shí)的總和宝与,加上先前通過這種方法添加的任何補(bǔ)充焚廊, length參數(shù)是 讀操作到目前為止已讀取的字節(jié)數(shù), 注意习劫,如果返回正數(shù)的話咆瘟,這個(gè)方法可能被一個(gè)單獨(dú)的讀取多次調(diào)用

           -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutWriteWithTag:(long)tag elapsed:(NSTimeInterval)elapsed bytesDone:(NSUInteger)length;
            如果一個(gè)寫操作已達(dá)到其超時(shí)但還沒完成時(shí)調(diào)用,同上

           -(void)onSocketDidSecure:(AsyncSocket *)sock;
           在socket成功完成ssl/tls協(xié)商時(shí)調(diào)用榜聂,此方法除非你使用提供startTLS方法時(shí)候才調(diào)用搞疗,
如果ssl/tls是無效的證書,socket將會(huì)立即關(guān)閉须肆,onSocket:willDisconnectWithError:代理方法竟會(huì)與特定的ssl錯(cuò)誤代碼一起調(diào)用

           -(BOOL)canSafelySetDelegate
           用來查看在改變它之前匿乃,是否帶有與當(dāng)前的委托有懸而未決的業(yè)務(wù)(讀/寫)。當(dāng)然豌汇,應(yīng)在安全連接或接受委托之前改變委托

          一旦接收或連接方法之一被調(diào)用幢炸,AsyncSocket實(shí)例會(huì)被鎖定,其他接收/連接方法在沒有先斷開socket不會(huì)被調(diào)用
          如果嘗試失敗或超時(shí)拒贱,這些方法要么返回NO 要么調(diào)用 onSocket:willDisconnectWithError: 或 onSockedDidDisconnect
          當(dāng)傳入的連接被接受宛徊,AsyncSocket調(diào)用多個(gè)委托方法佛嬉。這些方法按照時(shí)間順序排列:
             1.onSocket:didAcceptNewSocket:
             2.onSocket:wantsRunLoopForNewSocket:
             3. onSocketWillConnect:
           
          你的服務(wù)器的代碼將需要保留公認(rèn)的socket(如果要接受它),最好的地方是要做到這一點(diǎn)可能在onSocket:didAcceptNewSocket:方法    
         在讀和寫流已經(jīng)為新接受的socket設(shè)置闸天,onSocket:didConnectToHost:port 方法將在適當(dāng)?shù)倪\(yùn)行循環(huán)調(diào)用
         多線程注意暖呕,如果要想通過實(shí)施onSocket:wantsRunLoopForNewSocket:,移動(dòng)另一個(gè)新接受的socket去到另一個(gè)循環(huán)的socket苞氮。然后湾揽,應(yīng)該在調(diào)用讀和寫或者startTLS方法前,等待直到onSocket:didConnectToHost:port:方法笼吟。否則讀和寫時(shí)間原定于不正確的runloop库物,混亂可能會(huì)隨之而來


         -(BOOL)acceptOnPort:(UInit16)port error:(NSError **)errPtr;
         告訴socket開始聽取和接受制定端口上的連接,當(dāng)一個(gè)連接到來的時(shí)候贷帮,AsyncSocket實(shí)例將調(diào)用各種委托方法戚揭,socket將聽取所有可用的接口(wifi,以太網(wǎng)等)

         -(BOOL)connectToHost:(NSString *)hostname onPort:(UInt16)port error :(NSError **)errPtr;
         連接給定的主機(jī)和端口,主機(jī)hostname可以是域名或者是Ip地址

         -(BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError *)errPtr;
         連接到一個(gè)給定的地址撵枢,制定一個(gè)sockaddr結(jié)構(gòu)包裹住一個(gè)NSData對(duì)象,例如民晒,NSData對(duì)象從NSNetService的地址方法返回,如果有一個(gè)現(xiàn)有的sockaddr結(jié)構(gòu),可以將它轉(zhuǎn)換到一個(gè)NSData對(duì)象锄禽,像這樣:

struct sockaddr sa -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len];
struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len];

         -(void)disconnect;
            立即斷開镀虐,任何未處理的讀或?qū)懚紝⒈粊G棄
            如果socket還沒有斷開,在這個(gè)方法返回之前沟绪,onSocketDidDisconnect 委托方法將會(huì)被立即調(diào)用
             注意推薦釋放AsyncSocket實(shí)例的方式:
               [asyncSocket setDelegate:nil];
               [asyncSocket disconnect];
               [asyncSocket release];

          -(void)disconnectAfterReading;
             在已經(jīng)完成了所有懸而未決的讀取時(shí) 斷開,在調(diào)用之后,讀取和寫入方法將無用,socket將斷開 即使仍有待寫入

          - (NSString *)connectedHost;
          - (UInt16)connectedPort;
          - (NSString *)localHost;
          - (UInt16)localPort;
            返回本地和遠(yuǎn)程主機(jī)和端口給連接的socket空猜,如果沒有連接會(huì)返回nil或0,主機(jī)將會(huì)是一個(gè)IP地址

         -(NSData *)connectedAddress
         -(NSData *)localAddresss
            返回本地和遠(yuǎn)程的地址給連接的socket绽慈,指定一個(gè)socketaddr結(jié)構(gòu)包裹在一個(gè)NSData對(duì)象


            readData和writeData方法不會(huì)是block(它們是異步的)
           當(dāng)讀完成 onSocket:didReadData:withTag: 委托方法時(shí)調(diào)用
           當(dāng)寫完成 onSocket:didWriteDataWithTag: 委托方法時(shí)調(diào)用
           可以選擇任何讀/寫操作的超時(shí)設(shè)置(為了不超時(shí),使用負(fù)時(shí)間間隔辈毯。)
           如果讀/寫操作超時(shí)坝疼,相應(yīng)的 onSocket:shouldTimeout...委托方法被調(diào)用去選擇性地允許我們?nèi)パ娱L超時(shí)
           超時(shí)后,onSocket:willDisconnectWithError: 方法被調(diào)用,緊接著是 onSocketDidDisconnect
           tag是為了方便谆沃,可以使用它作為數(shù)組的索引钝凶、步數(shù)、state id 唁影、指針等 



        -(void)readDataWithTimeout:(NSTimeInterval)tiemout tag:(long)tag;
          讀取socket上第一次成為可用的字節(jié),如果timeout值是負(fù)數(shù)的耕陷,讀操作將不使用timeout

        - (void)readDataWithTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInterger)offset tag:(long)tag;
          讀取socket上第一次成為可用的字節(jié)
          字節(jié)將被追加到給定的字節(jié)緩沖區(qū),從給定的偏移量開始
          如果需要据沈,給定的緩沖區(qū)大小將會(huì)自動(dòng)增加
          如果timeout值是負(fù)數(shù)的哟沫,讀操作將不使用timeout
          如果緩沖區(qū)為空,socket會(huì)為我們創(chuàng)建一個(gè)緩沖區(qū)
          如果bufferOffset是大于給定的緩沖區(qū)的長度锌介,該方法將無用嗜诀,委托將不會(huì)被調(diào)用
          如果你傳遞一個(gè)緩沖區(qū)猾警,當(dāng)AsyncSocket在使用它的時(shí)候你不能以任何方式改變它
          完成之后,onSocket:didReadData:withTag 返回的數(shù)據(jù)將是一個(gè)給定的緩沖區(qū)的子集
          也就是說隆敢,它將會(huì)被引用到被追加的給定的緩沖區(qū)的字節(jié)

        -(void)readDataToLength:(NSUInterger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;
        讀取給定的字節(jié)數(shù)发皿,如果length為0,方法將無用拂蝎,委托將不會(huì)被調(diào)用

        -(void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)tiemout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
        讀取給定的字節(jié)數(shù),在給定的偏移開始穴墅,字節(jié)將被追加到給定的字節(jié)緩沖區(qū)

        -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
        讀取字節(jié)直到(包括)傳入的作為分隔的"data"參數(shù)
        如果傳遞0或者0長度的數(shù)據(jù),"data"參數(shù)匣屡,該方法將無用封救,委托將不會(huì)被調(diào)用
        從socket讀取一行,使用"data"參數(shù)作為行的分隔符 (如HTTP的CRLF)
        注意捣作,此方法不是字符集誉结,因此,如果一個(gè)分隔符出現(xiàn)券躁,它自然可以作為進(jìn)行編碼的一部分惩坑,讀取將提前結(jié)束

        -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
       讀取字節(jié)直到(包括)傳入的作為分隔的“data”參數(shù),在給定的偏移量開始也拜,字節(jié)將被追加到給定的字節(jié)緩沖區(qū)以舒。
       從socket讀取一行,使用"data"參數(shù)作為行的分隔符(如HTTP的CRLF)

       -(void)writeData:(NSData *)data withTimeout:(NSTimeInterval) timeout tag:(long)tag;
      將data寫入socket慢哈,當(dāng)完成的時(shí)候委托被調(diào)用 

       - (float)progressOfReadReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
       - (float)progressOfWriteReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
       返回當(dāng)前讀或?qū)懙倪M(jìn)度蔓钟,從0.0 到 1.0 或者 如果沒有讀/寫的時(shí)候返回Nan(使用isNan來檢查)

tag、done卵贱、total如果不為空的話滥沫,它們將會(huì)被填補(bǔ)

       - (void)startTLS:(NSDictionary *)tlsSettings;
       確保使用ssl/tls連接
       這方法可被隨時(shí)調(diào)用,tls握手將會(huì)發(fā)生在所有懸而未決的讀/寫完成之后键俱。這緊跟著一個(gè)發(fā)送依賴 StartTLS消息的協(xié)議選項(xiàng)兰绣,在排隊(duì)升級(jí)到TLS的同一時(shí)間,而不必等待寫入完成编振。在這個(gè)方法被調(diào)用后,任何讀寫計(jì)劃 將會(huì)發(fā)生在安全鏈接
       對(duì)于可能的keys和TLS設(shè)置的值是有據(jù)可查的
       一些可能的keys是:
          * - kCFStreamSSLLevel
          * - kCFStreamSSLAllowsExpiredCertificates
          * - kCFStreamSSLAllowsExpiredRoots
          * - kCFStreamSSLAllowsAnyRoot
          * - kCFStreamSSLValidatesCertificateChain
          * - kCFStreamSSLPeerName
          * - kCFStreamSSLCertificates
          * - kCFStreamSSLIsServer

       如果你傳遞空或者空字典缀辩,將使用默認(rèn)的字典
       默認(rèn)設(shè)置將檢查以確保由簽署可信的第三方證書機(jī)構(gòu)和沒有過期的遠(yuǎn)程連接的證書
       然而,它不會(huì)驗(yàn)證證書上的名字踪央,除非你給它一個(gè)名字臀玄,通過kCFStreamSSLPeerName鍵去驗(yàn)證
       這對(duì)安全的影響是重要的理解
       想象一下你正試圖創(chuàng)建一個(gè)到MySecureServer.com的安全連接,但因?yàn)橐粋€(gè)被攻擊的DNS服務(wù)器杯瞻,所以你的socket被定向到MaliciousServer.com
       如果你只是使用默認(rèn)設(shè)置镐牺,MaliciousServer.com 有一個(gè)有效的證書
       默認(rèn)設(shè)置將無法監(jiān)測(cè)到任何問題,因?yàn)樽C書是有效的
      在這個(gè)特殊的情況下魁莉,要妥善保護(hù)你的連接睬涧,應(yīng)設(shè)置kCFStreamSSLPeerName性質(zhì)為MySecureServer.com.
     如果事前你不知道對(duì)等的名字的遠(yuǎn)程主機(jī)(例如募胃,你不確認(rèn)它是domain.com" or "www.domain.com"),那么你可以使用默認(rèn)設(shè)置來驗(yàn)證證書畦浓,然后在獲得驗(yàn)證的發(fā)行后使用X509Certificate類來驗(yàn)證,X509Certificate類的CocoaAsyncSocket開源項(xiàng)目的一部分

     -(void)enablePrebuffering
     對(duì)于處理readDataToData請(qǐng)求痹束,數(shù)據(jù)是必須從socket以小增量的方式讀取出來的
     性能通過允許AsyncSocket去一次性讀大塊的數(shù)據(jù)和存儲(chǔ)任何一個(gè)小的內(nèi)部緩沖區(qū)溢出的東西來大大提高
     這被稱為預(yù)緩沖,就好像一些數(shù)據(jù)在你要求它之前就可能被讀取出來
     如果你經(jīng)常使用readDataToData讶请,使用預(yù)緩沖會(huì)有更好的性能祷嘶,尤其是在iphone上
     默認(rèn)的預(yù)緩沖狀態(tài)是由DEFAULT_PREBUFFERING 定義控制的,強(qiáng)烈建議設(shè)置其為yes
     這方法存在一些預(yù)緩沖需要一些不可預(yù)見的原因被默認(rèn)禁用的情況夺溢,這時(shí)论巍,這種方法存在允許當(dāng)就緒時(shí),可輕松啟用預(yù)緩沖

      -(BOOL)moveToRunLoop:(NSRunLoop *)runLoop;
      當(dāng)你創(chuàng)建一個(gè)AsyncSocket风响,它被添加到當(dāng)前線程runloop
      對(duì)于手動(dòng)創(chuàng)建的socket嘉汰,在線程上你打算使用它,它是最容易簡單的創(chuàng)建的線程上的socket
      當(dāng)一個(gè)新的socket被接受状勤,委托方法 onSocket:wantsRunLoopForNewSocket 會(huì)被調(diào)用 允許你在一個(gè)單獨(dú)的線程上放置socket鞋怀,這個(gè)工作最好結(jié)合在同一個(gè)線程池設(shè)計(jì)
      如果,但是持搜,在一個(gè)單獨(dú)的線程上密似,在之后的時(shí)間,你需要移動(dòng)一個(gè)socket葫盼,這個(gè)方法可以用來完成任務(wù)
      此方法必須從 當(dāng)前運(yùn)行的 線程/runloop 的socket 調(diào)用
      注意:此方法調(diào)用后残腌,所有進(jìn)一步的方法應(yīng)該從給定的runloop上調(diào)用這個(gè)對(duì)象
      此外,所有委托調(diào)用將會(huì)發(fā)送到給定的runloop


      - (BOOL)setRunLoopModes:(NSArray *)runLoopModes;
      - (BOOL)addRunLoopMode:(NSString *)runLoopMode;
      - (BOOL)removeRunLoopMode:(NSString *)runLoopMode;
       允許你配置 socket 使用的 運(yùn)行循環(huán)模式
       運(yùn)行循環(huán)模式設(shè)置默認(rèn)是NSRunLoopCommonModes
       如果你想你的socket 在其他模式下繼續(xù)操作贫导,你可能需要添加模式 NSModalPanelRunLoopMode 或者 NSEventTrackingRunLoopMode ,或者你可能只想使用 NSRunLoopCommonModes
       可接受的socket將自動(dòng) 繼承相同的運(yùn)行循環(huán)模式就像偵聽socket
       注意:NSRunLoopCommonModes 定義在10.5废累,對(duì)于之前的版本可使用 kCFRunLoopCommonModes

      -(NSArray *)runLoopModes
        返回當(dāng)前正在運(yùn)行的循環(huán)模式的AsyncSocket實(shí)例, run loop modes的默認(rèn)設(shè)置是NSDefaultRunLoopMode

      -(NSData *)unreadData;
     一個(gè)錯(cuò)誤的事件脱盲,在 onSocket:willDisconnectWithError: 將會(huì)被調(diào)用 去讀取留在socket上的任何數(shù)據(jù)

      + (NSData *)CRLFData;   // 0x0D0A

各方法的解析
-(void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
發(fā)生錯(cuò)誤,socket關(guān)閉日缨,可以在call-back過程調(diào)用"unreadData"去取得socket的最后的數(shù)據(jù)字節(jié)钱反,當(dāng)連接的時(shí)候,該委托方法在 onSocket:didAcceptNewSocket: 或者 onSocket:didConnectToHost: 之前調(diào)用

  -(void)onSocketDidDisconnect:(ASyncSocket *)sock;
  當(dāng)socket由于或沒有錯(cuò)誤而斷開連接匣距,如果你想要在斷開連接后release socket面哥,在此方法工作,而在onSocket:willDisconnectWithError 釋放則不安全

   -(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket;
    當(dāng)產(chǎn)生一個(gè)socket去處理連接時(shí)調(diào)用毅待,此方法會(huì)返回 線程上的run-loop 的新的socket和其應(yīng)處理的委托尚卫,如果省略,則使用[NSRunLoop cunrrentRunLoop]

      -(BOOL)onSocketWillConnect:(AsyncSocket *)sock;

   -(void)onSocket:(AsyncSocket *)sock didConnectToHost :(NSString *)host port:(UINt16)port;
      當(dāng)socket連接正準(zhǔn)備讀和寫的時(shí)候調(diào)用尸红,host屬性是一個(gè)IP地址吱涉,而不是一個(gè)DNS 名稱

     -(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long) tag;
     當(dāng)socket已完成所要求的數(shù)據(jù)讀入內(nèi)存時(shí)調(diào)用刹泄,如果有錯(cuò)誤則不調(diào)用

     -(void)onSocket:(Asyncsocket *)sock didReadPartialDataOfLength:(NSUInteger)partiaLength tag:(long)tag;
       當(dāng)一個(gè)socket讀取數(shù)據(jù),但尚未完成讀操作的時(shí)候調(diào)用怎爵,如果使用 readToData: or readToLength: 方法 會(huì)發(fā)生,可以被用來更新進(jìn)度條等東西

        -(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
         當(dāng)一個(gè)socket已完成請(qǐng)求數(shù)據(jù)的寫入時(shí)候調(diào)用

        -(void)onSocket:(AsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag;
         當(dāng)一個(gè)socket寫入一些數(shù)據(jù)特石,但還沒有完成整個(gè)寫入時(shí)調(diào)用,它可以用來更新進(jìn)度條等東西

           -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag elapsed:(NSTimeInterval)exapsed bytesDone:(NSUInteger)length
          使用讀操作已超時(shí)但還沒完成時(shí)調(diào)用鳖链,此方法允許隨意延遲超時(shí)姆蘸,如果返回一個(gè)正的時(shí)間間隔,讀取的超時(shí)將有一定量的擴(kuò)展芙委,如果不實(shí)現(xiàn)這個(gè)方法逞敷,或會(huì)像往常一樣返回一個(gè)負(fù)的時(shí)間間隔,elapsed參數(shù)是  原超時(shí)的總和灌侣,加上先前通過這種方法添加的任何補(bǔ)充推捐, length參數(shù)是 讀操作到目前為止已讀取的字節(jié)數(shù), 注意顶瞳,如果返回正數(shù)的話玖姑,這個(gè)方法可能被一個(gè)單獨(dú)的讀取多次調(diào)用

           -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutWriteWithTag:(long)tag elapsed:(NSTimeInterval)elapsed bytesDone:(NSUInteger)length;
            如果一個(gè)寫操作已達(dá)到其超時(shí)但還沒完成時(shí)調(diào)用,同上

           -(void)onSocketDidSecure:(AsyncSocket *)sock;
           在socket成功完成ssl/tls協(xié)商時(shí)調(diào)用慨菱,此方法除非你使用提供startTLS方法時(shí)候才調(diào)用焰络,
如果ssl/tls是無效的證書,socket將會(huì)立即關(guān)閉符喝,onSocket:willDisconnectWithError:代理方法竟會(huì)與特定的ssl錯(cuò)誤代碼一起調(diào)用

           -(BOOL)canSafelySetDelegate
           用來查看在改變它之前闪彼,是否帶有與當(dāng)前的委托有懸而未決的業(yè)務(wù)(讀/寫)。當(dāng)然协饲,應(yīng)在安全連接或接受委托之前改變委托

          一旦接收或連接方法之一被調(diào)用畏腕,AsyncSocket實(shí)例會(huì)被鎖定,其他接收/連接方法在沒有先斷開socket不會(huì)被調(diào)用
          如果嘗試失敗或超時(shí)茉稠,這些方法要么返回NO 要么調(diào)用 onSocket:willDisconnectWithError: 或 onSockedDidDisconnect
          當(dāng)傳入的連接被接受描馅,AsyncSocket調(diào)用多個(gè)委托方法。這些方法按照時(shí)間順序排列:
             1.onSocket:didAcceptNewSocket:
             2.onSocket:wantsRunLoopForNewSocket:
             3. onSocketWillConnect:
           
          你的服務(wù)器的代碼將需要保留公認(rèn)的socket(如果要接受它)而线,最好的地方是要做到這一點(diǎn)可能在onSocket:didAcceptNewSocket:方法    
         在讀和寫流已經(jīng)為新接受的socket設(shè)置铭污,onSocket:didConnectToHost:port 方法將在適當(dāng)?shù)倪\(yùn)行循環(huán)調(diào)用
         多線程注意,如果要想通過實(shí)施onSocket:wantsRunLoopForNewSocket:膀篮,移動(dòng)另一個(gè)新接受的socket去到另一個(gè)循環(huán)的socket嘹狞。然后,應(yīng)該在調(diào)用讀和寫或者startTLS方法前誓竿,等待直到onSocket:didConnectToHost:port:方法磅网。否則讀和寫時(shí)間原定于不正確的runloop,混亂可能會(huì)隨之而來


         -(BOOL)acceptOnPort:(UInit16)port error:(NSError **)errPtr;
         告訴socket開始聽取和接受制定端口上的連接筷屡,當(dāng)一個(gè)連接到來的時(shí)候涧偷,AsyncSocket實(shí)例將調(diào)用各種委托方法簸喂,socket將聽取所有可用的接口(wifi,以太網(wǎng)等)

         -(BOOL)connectToHost:(NSString *)hostname onPort:(UInt16)port error :(NSError **)errPtr;
         連接給定的主機(jī)和端口,主機(jī)hostname可以是域名或者是Ip地址

         -(BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError *)errPtr;
         連接到一個(gè)給定的地址嫂丙,制定一個(gè)sockaddr結(jié)構(gòu)包裹住一個(gè)NSData對(duì)象,例如娘赴,NSData對(duì)象從NSNetService的地址方法返回,如果有一個(gè)現(xiàn)有的sockaddr結(jié)構(gòu),可以將它轉(zhuǎn)換到一個(gè)NSData對(duì)象跟啤,像這樣:

struct sockaddr sa -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len];
struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len];

         -(void)disconnect;
            立即斷開诽表,任何未處理的讀或?qū)懚紝⒈粊G棄
            如果socket還沒有斷開,在這個(gè)方法返回之前隅肥,onSocketDidDisconnect 委托方法將會(huì)被立即調(diào)用
             注意推薦釋放AsyncSocket實(shí)例的方式:
               [asyncSocket setDelegate:nil];
               [asyncSocket disconnect];
               [asyncSocket release];

          -(void)disconnectAfterReading;
             在已經(jīng)完成了所有懸而未決的讀取時(shí) 斷開,在調(diào)用之后竿奏,讀取和寫入方法將無用,socket將斷開 即使仍有待寫入

          - (NSString *)connectedHost;
          - (UInt16)connectedPort;
          - (NSString *)localHost;
          - (UInt16)localPort;
            返回本地和遠(yuǎn)程主機(jī)和端口給連接的socket,如果沒有連接會(huì)返回nil或0,主機(jī)將會(huì)是一個(gè)IP地址

         -(NSData *)connectedAddress
         -(NSData *)localAddresss
            返回本地和遠(yuǎn)程的地址給連接的socket腥放,指定一個(gè)socketaddr結(jié)構(gòu)包裹在一個(gè)NSData對(duì)象


            readData和writeData方法不會(huì)是block(它們是異步的)
           當(dāng)讀完成 onSocket:didReadData:withTag: 委托方法時(shí)調(diào)用
           當(dāng)寫完成 onSocket:didWriteDataWithTag: 委托方法時(shí)調(diào)用
           可以選擇任何讀/寫操作的超時(shí)設(shè)置(為了不超時(shí)泛啸,使用負(fù)時(shí)間間隔。)
           如果讀/寫操作超時(shí)秃症,相應(yīng)的 onSocket:shouldTimeout...委托方法被調(diào)用去選擇性地允許我們?nèi)パ娱L超時(shí)
           超時(shí)后候址,onSocket:willDisconnectWithError: 方法被調(diào)用,緊接著是 onSocketDidDisconnect
           tag是為了方便,可以使用它作為數(shù)組的索引种柑、步數(shù)岗仑、state id 、指針等 



        -(void)readDataWithTimeout:(NSTimeInterval)tiemout tag:(long)tag;
          讀取socket上第一次成為可用的字節(jié),如果timeout值是負(fù)數(shù)的聚请,讀操作將不使用timeout

        - (void)readDataWithTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInterger)offset tag:(long)tag;
          讀取socket上第一次成為可用的字節(jié)
          字節(jié)將被追加到給定的字節(jié)緩沖區(qū)荠雕,從給定的偏移量開始
          如果需要,給定的緩沖區(qū)大小將會(huì)自動(dòng)增加
          如果timeout值是負(fù)數(shù)的驶赏,讀操作將不使用timeout
          如果緩沖區(qū)為空炸卑,socket會(huì)為我們創(chuàng)建一個(gè)緩沖區(qū)
          如果bufferOffset是大于給定的緩沖區(qū)的長度,該方法將無用煤傍,委托將不會(huì)被調(diào)用
          如果你傳遞一個(gè)緩沖區(qū)盖文,當(dāng)AsyncSocket在使用它的時(shí)候你不能以任何方式改變它
          完成之后,onSocket:didReadData:withTag 返回的數(shù)據(jù)將是一個(gè)給定的緩沖區(qū)的子集
          也就是說蚯姆,它將會(huì)被引用到被追加的給定的緩沖區(qū)的字節(jié)

        -(void)readDataToLength:(NSUInterger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;
        讀取給定的字節(jié)數(shù)椅寺,如果length為0,方法將無用蒋失,委托將不會(huì)被調(diào)用

        -(void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)tiemout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
        讀取給定的字節(jié)數(shù),在給定的偏移開始,字節(jié)將被追加到給定的字節(jié)緩沖區(qū)

        -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
        讀取字節(jié)直到(包括)傳入的作為分隔的"data"參數(shù)
        如果傳遞0或者0長度的數(shù)據(jù)桐玻,"data"參數(shù)篙挽,該方法將無用,委托將不會(huì)被調(diào)用
        從socket讀取一行镊靴,使用"data"參數(shù)作為行的分隔符 (如HTTP的CRLF)
        注意铣卡,此方法不是字符集链韭,因此,如果一個(gè)分隔符出現(xiàn)煮落,它自然可以作為進(jìn)行編碼的一部分敞峭,讀取將提前結(jié)束

        -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
       讀取字節(jié)直到(包括)傳入的作為分隔的“data”參數(shù),在給定的偏移量開始蝉仇,字節(jié)將被追加到給定的字節(jié)緩沖區(qū)旋讹。
       從socket讀取一行,使用"data"參數(shù)作為行的分隔符(如HTTP的CRLF)

       -(void)writeData:(NSData *)data withTimeout:(NSTimeInterval) timeout tag:(long)tag;
      將data寫入socket轿衔,當(dāng)完成的時(shí)候委托被調(diào)用 

       - (float)progressOfReadReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
       - (float)progressOfWriteReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
       返回當(dāng)前讀或?qū)懙倪M(jìn)度沉迹,從0.0 到 1.0 或者 如果沒有讀/寫的時(shí)候返回Nan(使用isNan來檢查)

tag、done害驹、total如果不為空的話鞭呕,它們將會(huì)被填補(bǔ)

       - (void)startTLS:(NSDictionary *)tlsSettings;
       確保使用ssl/tls連接
       這方法可被隨時(shí)調(diào)用,tls握手將會(huì)發(fā)生在所有懸而未決的讀/寫完成之后宛官。這緊跟著一個(gè)發(fā)送依賴 StartTLS消息的協(xié)議選項(xiàng)葫松,在排隊(duì)升級(jí)到TLS的同一時(shí)間,而不必等待寫入完成底洗。在這個(gè)方法被調(diào)用后,任何讀寫計(jì)劃 將會(huì)發(fā)生在安全鏈接
       對(duì)于可能的keys和TLS設(shè)置的值是有據(jù)可查的
       一些可能的keys是:
          * - kCFStreamSSLLevel
          * - kCFStreamSSLAllowsExpiredCertificates
          * - kCFStreamSSLAllowsExpiredRoots
          * - kCFStreamSSLAllowsAnyRoot
          * - kCFStreamSSLValidatesCertificateChain
          * - kCFStreamSSLPeerName
          * - kCFStreamSSLCertificates
          * - kCFStreamSSLIsServer

       如果你傳遞空或者空字典腋么,將使用默認(rèn)的字典
       默認(rèn)設(shè)置將檢查以確保由簽署可信的第三方證書機(jī)構(gòu)和沒有過期的遠(yuǎn)程連接的證書
       然而,它不會(huì)驗(yàn)證證書上的名字枷恕,除非你給它一個(gè)名字党晋,通過kCFStreamSSLPeerName鍵去驗(yàn)證
       這對(duì)安全的影響是重要的理解
       想象一下你正試圖創(chuàng)建一個(gè)到MySecureServer.com的安全連接,但因?yàn)橐粋€(gè)被攻擊的DNS服務(wù)器徐块,所以你的socket被定向到MaliciousServer.com
       如果你只是使用默認(rèn)設(shè)置未玻,MaliciousServer.com 有一個(gè)有效的證書
       默認(rèn)設(shè)置將無法監(jiān)測(cè)到任何問題,因?yàn)樽C書是有效的
      在這個(gè)特殊的情況下胡控,要妥善保護(hù)你的連接扳剿,應(yīng)設(shè)置kCFStreamSSLPeerName性質(zhì)為MySecureServer.com.
     如果事前你不知道對(duì)等的名字的遠(yuǎn)程主機(jī)(例如,你不確認(rèn)它是domain.com" or "www.domain.com")昼激,那么你可以使用默認(rèn)設(shè)置來驗(yàn)證證書庇绽,然后在獲得驗(yàn)證的發(fā)行后使用X509Certificate類來驗(yàn)證,X509Certificate類的CocoaAsyncSocket開源項(xiàng)目的一部分

     -(void)enablePrebuffering
     對(duì)于處理readDataToData請(qǐng)求,數(shù)據(jù)是必須從socket以小增量的方式讀取出來的
     性能通過允許AsyncSocket去一次性讀大塊的數(shù)據(jù)和存儲(chǔ)任何一個(gè)小的內(nèi)部緩沖區(qū)溢出的東西來大大提高
     這被稱為預(yù)緩沖橙困,就好像一些數(shù)據(jù)在你要求它之前就可能被讀取出來
     如果你經(jīng)常使用readDataToData瞧掺,使用預(yù)緩沖會(huì)有更好的性能,尤其是在iphone上
     默認(rèn)的預(yù)緩沖狀態(tài)是由DEFAULT_PREBUFFERING 定義控制的凡傅,強(qiáng)烈建議設(shè)置其為yes
     這方法存在一些預(yù)緩沖需要一些不可預(yù)見的原因被默認(rèn)禁用的情況辟狈,這時(shí),這種方法存在允許當(dāng)就緒時(shí),可輕松啟用預(yù)緩沖

      -(BOOL)moveToRunLoop:(NSRunLoop *)runLoop;
      當(dāng)你創(chuàng)建一個(gè)AsyncSocket哼转,它被添加到當(dāng)前線程runloop
      對(duì)于手動(dòng)創(chuàng)建的socket明未,在線程上你打算使用它,它是最容易簡單的創(chuàng)建的線程上的socket
      當(dāng)一個(gè)新的socket被接受壹蔓,委托方法 onSocket:wantsRunLoopForNewSocket 會(huì)被調(diào)用 允許你在一個(gè)單獨(dú)的線程上放置socket趟妥,這個(gè)工作最好結(jié)合在同一個(gè)線程池設(shè)計(jì)
      如果,但是佣蓉,在一個(gè)單獨(dú)的線程上披摄,在之后的時(shí)間,你需要移動(dòng)一個(gè)socket偏螺,這個(gè)方法可以用來完成任務(wù)
      此方法必須從 當(dāng)前運(yùn)行的 線程/runloop 的socket 調(diào)用
      注意:此方法調(diào)用后行疏,所有進(jìn)一步的方法應(yīng)該從給定的runloop上調(diào)用這個(gè)對(duì)象
      此外,所有委托調(diào)用將會(huì)發(fā)送到給定的runloop


      - (BOOL)setRunLoopModes:(NSArray *)runLoopModes;
      - (BOOL)addRunLoopMode:(NSString *)runLoopMode;
      - (BOOL)removeRunLoopMode:(NSString *)runLoopMode;
       允許你配置 socket 使用的 運(yùn)行循環(huán)模式
       運(yùn)行循環(huán)模式設(shè)置默認(rèn)是NSRunLoopCommonModes
       如果你想你的socket 在其他模式下繼續(xù)操作,你可能需要添加模式 NSModalPanelRunLoopMode 或者 NSEventTrackingRunLoopMode ,或者你可能只想使用 NSRunLoopCommonModes
       可接受的socket將自動(dòng) 繼承相同的運(yùn)行循環(huán)模式就像偵聽socket
       注意:NSRunLoopCommonModes 定義在10.5,對(duì)于之前的版本可使用 kCFRunLoopCommonModes

      -(NSArray *)runLoopModes
        返回當(dāng)前正在運(yùn)行的循環(huán)模式的AsyncSocket實(shí)例板壮, run loop modes的默認(rèn)設(shè)置是NSDefaultRunLoopMode

      -(NSData *)unreadData;
     一個(gè)錯(cuò)誤的事件,在 onSocket:willDisconnectWithError: 將會(huì)被調(diào)用 去讀取留在socket上的任何數(shù)據(jù)

      + (NSData *)CRLFData;   // 0x0D0A

各方法的解析
-(void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
發(fā)生錯(cuò)誤贞让,socket關(guān)閉,可以在call-back過程調(diào)用"unreadData"去取得socket的最后的數(shù)據(jù)字節(jié)柳譬,當(dāng)連接的時(shí)候喳张,該委托方法在 onSocket:didAcceptNewSocket: 或者 onSocket:didConnectToHost: 之前調(diào)用

  -(void)onSocketDidDisconnect:(ASyncSocket *)sock;
  當(dāng)socket由于或沒有錯(cuò)誤而斷開連接,如果你想要在斷開連接后release socket美澳,在此方法工作销部,而在onSocket:willDisconnectWithError 釋放則不安全

   -(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket;
    當(dāng)產(chǎn)生一個(gè)socket去處理連接時(shí)調(diào)用,此方法會(huì)返回 線程上的run-loop 的新的socket和其應(yīng)處理的委托制跟,如果省略舅桩,則使用[NSRunLoop cunrrentRunLoop]

      -(BOOL)onSocketWillConnect:(AsyncSocket *)sock;

   -(void)onSocket:(AsyncSocket *)sock didConnectToHost :(NSString *)host port:(UINt16)port;
      當(dāng)socket連接正準(zhǔn)備讀和寫的時(shí)候調(diào)用,host屬性是一個(gè)IP地址雨膨,而不是一個(gè)DNS 名稱

     -(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long) tag;
     當(dāng)socket已完成所要求的數(shù)據(jù)讀入內(nèi)存時(shí)調(diào)用擂涛,如果有錯(cuò)誤則不調(diào)用

     -(void)onSocket:(Asyncsocket *)sock didReadPartialDataOfLength:(NSUInteger)partiaLength tag:(long)tag;
       當(dāng)一個(gè)socket讀取數(shù)據(jù),但尚未完成讀操作的時(shí)候調(diào)用聊记,如果使用 readToData: or readToLength: 方法 會(huì)發(fā)生,可以被用來更新進(jìn)度條等東西

        -(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
         當(dāng)一個(gè)socket已完成請(qǐng)求數(shù)據(jù)的寫入時(shí)候調(diào)用

        -(void)onSocket:(AsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag;
         當(dāng)一個(gè)socket寫入一些數(shù)據(jù)撒妈,但還沒有完成整個(gè)寫入時(shí)調(diào)用,它可以用來更新進(jìn)度條等東西

           -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag elapsed:(NSTimeInterval)exapsed bytesDone:(NSUInteger)length
          使用讀操作已超時(shí)但還沒完成時(shí)調(diào)用排监,此方法允許隨意延遲超時(shí)狰右,如果返回一個(gè)正的時(shí)間間隔,讀取的超時(shí)將有一定量的擴(kuò)展舆床,如果不實(shí)現(xiàn)這個(gè)方法棋蚌,或會(huì)像往常一樣返回一個(gè)負(fù)的時(shí)間間隔,elapsed參數(shù)是  原超時(shí)的總和,加上先前通過這種方法添加的任何補(bǔ)充附鸽, length參數(shù)是 讀操作到目前為止已讀取的字節(jié)數(shù), 注意瞒瘸,如果返回正數(shù)的話坷备,這個(gè)方法可能被一個(gè)單獨(dú)的讀取多次調(diào)用

           -(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutWriteWithTag:(long)tag elapsed:(NSTimeInterval)elapsed bytesDone:(NSUInteger)length;
            如果一個(gè)寫操作已達(dá)到其超時(shí)但還沒完成時(shí)調(diào)用,同上

           -(void)onSocketDidSecure:(AsyncSocket *)sock;
           在socket成功完成ssl/tls協(xié)商時(shí)調(diào)用情臭,此方法除非你使用提供startTLS方法時(shí)候才調(diào)用省撑,
如果ssl/tls是無效的證書,socket將會(huì)立即關(guān)閉俯在,onSocket:willDisconnectWithError:代理方法竟會(huì)與特定的ssl錯(cuò)誤代碼一起調(diào)用

           -(BOOL)canSafelySetDelegate
           用來查看在改變它之前竟秫,是否帶有與當(dāng)前的委托有懸而未決的業(yè)務(wù)(讀/寫)。當(dāng)然跷乐,應(yīng)在安全連接或接受委托之前改變委托

          一旦接收或連接方法之一被調(diào)用肥败,AsyncSocket實(shí)例會(huì)被鎖定,其他接收/連接方法在沒有先斷開socket不會(huì)被調(diào)用
          如果嘗試失敗或超時(shí)愕提,這些方法要么返回NO 要么調(diào)用 onSocket:willDisconnectWithError: 或 onSockedDidDisconnect
          當(dāng)傳入的連接被接受馒稍,AsyncSocket調(diào)用多個(gè)委托方法。這些方法按照時(shí)間順序排列:
             1.onSocket:didAcceptNewSocket:
             2.onSocket:wantsRunLoopForNewSocket:
             3. onSocketWillConnect:
           
          你的服務(wù)器的代碼將需要保留公認(rèn)的socket(如果要接受它)浅侨,最好的地方是要做到這一點(diǎn)可能在onSocket:didAcceptNewSocket:方法    
         在讀和寫流已經(jīng)為新接受的socket設(shè)置纽谒,onSocket:didConnectToHost:port 方法將在適當(dāng)?shù)倪\(yùn)行循環(huán)調(diào)用
         多線程注意,如果要想通過實(shí)施onSocket:wantsRunLoopForNewSocket:如输,移動(dòng)另一個(gè)新接受的socket去到另一個(gè)循環(huán)的socket鼓黔。然后,應(yīng)該在調(diào)用讀和寫或者startTLS方法前不见,等待直到onSocket:didConnectToHost:port:方法澳化。否則讀和寫時(shí)間原定于不正確的runloop,混亂可能會(huì)隨之而來


         -(BOOL)acceptOnPort:(UInit16)port error:(NSError **)errPtr;
         告訴socket開始聽取和接受制定端口上的連接脖祈,當(dāng)一個(gè)連接到來的時(shí)候肆捕,AsyncSocket實(shí)例將調(diào)用各種委托方法,socket將聽取所有可用的接口(wifi,以太網(wǎng)等)

         -(BOOL)connectToHost:(NSString *)hostname onPort:(UInt16)port error :(NSError **)errPtr;
         連接給定的主機(jī)和端口盖高,主機(jī)hostname可以是域名或者是Ip地址

         -(BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError *)errPtr;
         連接到一個(gè)給定的地址慎陵,制定一個(gè)sockaddr結(jié)構(gòu)包裹住一個(gè)NSData對(duì)象,例如,NSData對(duì)象從NSNetService的地址方法返回,如果有一個(gè)現(xiàn)有的sockaddr結(jié)構(gòu)喻奥,可以將它轉(zhuǎn)換到一個(gè)NSData對(duì)象席纽,像這樣:

struct sockaddr sa -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len];
struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len];

         -(void)disconnect;
            立即斷開,任何未處理的讀或?qū)懚紝⒈粊G棄
            如果socket還沒有斷開撞蚕,在這個(gè)方法返回之前润梯,onSocketDidDisconnect 委托方法將會(huì)被立即調(diào)用
             注意推薦釋放AsyncSocket實(shí)例的方式:
               [asyncSocket setDelegate:nil];
               [asyncSocket disconnect];
               [asyncSocket release];

          -(void)disconnectAfterReading;
             在已經(jīng)完成了所有懸而未決的讀取時(shí) 斷開,在調(diào)用之后,讀取和寫入方法將無用,socket將斷開 即使仍有待寫入

          - (NSString *)connectedHost;
          - (UInt16)connectedPort;
          - (NSString *)localHost;
          - (UInt16)localPort;
            返回本地和遠(yuǎn)程主機(jī)和端口給連接的socket,如果沒有連接會(huì)返回nil或0,主機(jī)將會(huì)是一個(gè)IP地址

         -(NSData *)connectedAddress
         -(NSData *)localAddresss
            返回本地和遠(yuǎn)程的地址給連接的socket纺铭,指定一個(gè)socketaddr結(jié)構(gòu)包裹在一個(gè)NSData對(duì)象


            readData和writeData方法不會(huì)是block(它們是異步的)
           當(dāng)讀完成 onSocket:didReadData:withTag: 委托方法時(shí)調(diào)用
           當(dāng)寫完成 onSocket:didWriteDataWithTag: 委托方法時(shí)調(diào)用
           可以選擇任何讀/寫操作的超時(shí)設(shè)置(為了不超時(shí)寇钉,使用負(fù)時(shí)間間隔。)
           如果讀/寫操作超時(shí)舶赔,相應(yīng)的 onSocket:shouldTimeout...委托方法被調(diào)用去選擇性地允許我們?nèi)パ娱L超時(shí)
           超時(shí)后扫倡,onSocket:willDisconnectWithError: 方法被調(diào)用,緊接著是 onSocketDidDisconnect
           tag是為了方便,可以使用它作為數(shù)組的索引竟纳、步數(shù)撵溃、state id 、指針等 



        -(void)readDataWithTimeout:(NSTimeInterval)tiemout tag:(long)tag;
          讀取socket上第一次成為可用的字節(jié),如果timeout值是負(fù)數(shù)的锥累,讀操作將不使用timeout

        - (void)readDataWithTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInterger)offset tag:(long)tag;
          讀取socket上第一次成為可用的字節(jié)
          字節(jié)將被追加到給定的字節(jié)緩沖區(qū)缘挑,從給定的偏移量開始
          如果需要,給定的緩沖區(qū)大小將會(huì)自動(dòng)增加
          如果timeout值是負(fù)數(shù)的桶略,讀操作將不使用timeout
          如果緩沖區(qū)為空语淘,socket會(huì)為我們創(chuàng)建一個(gè)緩沖區(qū)
          如果bufferOffset是大于給定的緩沖區(qū)的長度,該方法將無用删性,委托將不會(huì)被調(diào)用
          如果你傳遞一個(gè)緩沖區(qū)亏娜,當(dāng)AsyncSocket在使用它的時(shí)候你不能以任何方式改變它
          完成之后,onSocket:didReadData:withTag 返回的數(shù)據(jù)將是一個(gè)給定的緩沖區(qū)的子集
          也就是說蹬挺,它將會(huì)被引用到被追加的給定的緩沖區(qū)的字節(jié)

        -(void)readDataToLength:(NSUInterger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;
        讀取給定的字節(jié)數(shù)维贺,如果length為0,方法將無用巴帮,委托將不會(huì)被調(diào)用

        -(void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)tiemout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
        讀取給定的字節(jié)數(shù),在給定的偏移開始溯泣,字節(jié)將被追加到給定的字節(jié)緩沖區(qū)

        -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
        讀取字節(jié)直到(包括)傳入的作為分隔的"data"參數(shù)
        如果傳遞0或者0長度的數(shù)據(jù),"data"參數(shù)榕茧,該方法將無用垃沦,委托將不會(huì)被調(diào)用
        從socket讀取一行,使用"data"參數(shù)作為行的分隔符 (如HTTP的CRLF)
        注意用押,此方法不是字符集肢簿,因此,如果一個(gè)分隔符出現(xiàn)蜻拨,它自然可以作為進(jìn)行編碼的一部分池充,讀取將提前結(jié)束

        -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
       讀取字節(jié)直到(包括)傳入的作為分隔的“data”參數(shù),在給定的偏移量開始缎讼,字節(jié)將被追加到給定的字節(jié)緩沖區(qū)收夸。
       從socket讀取一行,使用"data"參數(shù)作為行的分隔符(如HTTP的CRLF)

       -(void)writeData:(NSData *)data withTimeout:(NSTimeInterval) timeout tag:(long)tag;
      將data寫入socket血崭,當(dāng)完成的時(shí)候委托被調(diào)用 

       - (float)progressOfReadReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
       - (float)progressOfWriteReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
       返回當(dāng)前讀或?qū)懙倪M(jìn)度卧惜,從0.0 到 1.0 或者 如果沒有讀/寫的時(shí)候返回Nan(使用isNan來檢查)

tag厘灼、done、total如果不為空的話咽瓷,它們將會(huì)被填補(bǔ)

       - (void)startTLS:(NSDictionary *)tlsSettings;
       確保使用ssl/tls連接
       這方法可被隨時(shí)調(diào)用设凹,tls握手將會(huì)發(fā)生在所有懸而未決的讀/寫完成之后。這緊跟著一個(gè)發(fā)送依賴 StartTLS消息的協(xié)議選項(xiàng)茅姜,在排隊(duì)升級(jí)到TLS的同一時(shí)間围来,而不必等待寫入完成。在這個(gè)方法被調(diào)用后,任何讀寫計(jì)劃 將會(huì)發(fā)生在安全鏈接
       對(duì)于可能的keys和TLS設(shè)置的值是有據(jù)可查的
       一些可能的keys是:
          * - kCFStreamSSLLevel
          * - kCFStreamSSLAllowsExpiredCertificates
          * - kCFStreamSSLAllowsExpiredRoots
          * - kCFStreamSSLAllowsAnyRoot
          * - kCFStreamSSLValidatesCertificateChain
          * - kCFStreamSSLPeerName
          * - kCFStreamSSLCertificates
          * - kCFStreamSSLIsServer

       如果你傳遞空或者空字典匈睁,將使用默認(rèn)的字典
       默認(rèn)設(shè)置將檢查以確保由簽署可信的第三方證書機(jī)構(gòu)和沒有過期的遠(yuǎn)程連接的證書
       然而,它不會(huì)驗(yàn)證證書上的名字桶错,除非你給它一個(gè)名字航唆,通過kCFStreamSSLPeerName鍵去驗(yàn)證
       這對(duì)安全的影響是重要的理解
       想象一下你正試圖創(chuàng)建一個(gè)到MySecureServer.com的安全連接,但因?yàn)橐粋€(gè)被攻擊的DNS服務(wù)器院刁,所以你的socket被定向到MaliciousServer.com
       如果你只是使用默認(rèn)設(shè)置糯钙,MaliciousServer.com 有一個(gè)有效的證書
       默認(rèn)設(shè)置將無法監(jiān)測(cè)到任何問題,因?yàn)樽C書是有效的
      在這個(gè)特殊的情況下退腥,要妥善保護(hù)你的連接任岸,應(yīng)設(shè)置kCFStreamSSLPeerName性質(zhì)為MySecureServer.com.
     如果事前你不知道對(duì)等的名字的遠(yuǎn)程主機(jī)(例如,你不確認(rèn)它是domain.com" or "www.domain.com")狡刘,那么你可以使用默認(rèn)設(shè)置來驗(yàn)證證書享潜,然后在獲得驗(yàn)證的發(fā)行后使用X509Certificate類來驗(yàn)證,X509Certificate類的CocoaAsyncSocket開源項(xiàng)目的一部分

     -(void)enablePrebuffering
     對(duì)于處理readDataToData請(qǐng)求,數(shù)據(jù)是必須從socket以小增量的方式讀取出來的
     性能通過允許AsyncSocket去一次性讀大塊的數(shù)據(jù)和存儲(chǔ)任何一個(gè)小的內(nèi)部緩沖區(qū)溢出的東西來大大提高
     這被稱為預(yù)緩沖嗅蔬,就好像一些數(shù)據(jù)在你要求它之前就可能被讀取出來
     如果你經(jīng)常使用readDataToData剑按,使用預(yù)緩沖會(huì)有更好的性能,尤其是在iphone上
     默認(rèn)的預(yù)緩沖狀態(tài)是由DEFAULT_PREBUFFERING 定義控制的澜术,強(qiáng)烈建議設(shè)置其為yes
     這方法存在一些預(yù)緩沖需要一些不可預(yù)見的原因被默認(rèn)禁用的情況艺蝴,這時(shí),這種方法存在允許當(dāng)就緒時(shí)鸟废,可輕松啟用預(yù)緩沖

      -(BOOL)moveToRunLoop:(NSRunLoop *)runLoop;
      當(dāng)你創(chuàng)建一個(gè)AsyncSocket猜敢,它被添加到當(dāng)前線程runloop
      對(duì)于手動(dòng)創(chuàng)建的socket,在線程上你打算使用它盒延,它是最容易簡單的創(chuàng)建的線程上的socket
      當(dāng)一個(gè)新的socket被接受缩擂,委托方法 onSocket:wantsRunLoopForNewSocket 會(huì)被調(diào)用 允許你在一個(gè)單獨(dú)的線程上放置socket,這個(gè)工作最好結(jié)合在同一個(gè)線程池設(shè)計(jì)
      如果兰英,但是撇叁,在一個(gè)單獨(dú)的線程上,在之后的時(shí)間畦贸,你需要移動(dòng)一個(gè)socket陨闹,這個(gè)方法可以用來完成任務(wù)
      此方法必須從 當(dāng)前運(yùn)行的 線程/runloop 的socket 調(diào)用
      注意:此方法調(diào)用后楞捂,所有進(jìn)一步的方法應(yīng)該從給定的runloop上調(diào)用這個(gè)對(duì)象
      此外,所有委托調(diào)用將會(huì)發(fā)送到給定的runloop


      - (BOOL)setRunLoopModes:(NSArray *)runLoopModes;
      - (BOOL)addRunLoopMode:(NSString *)runLoopMode;
      - (BOOL)removeRunLoopMode:(NSString *)runLoopMode;
       允許你配置 socket 使用的 運(yùn)行循環(huán)模式
       運(yùn)行循環(huán)模式設(shè)置默認(rèn)是NSRunLoopCommonModes
       如果你想你的socket 在其他模式下繼續(xù)操作趋厉,你可能需要添加模式 NSModalPanelRunLoopMode 或者 NSEventTrackingRunLoopMode ,或者你可能只想使用 NSRunLoopCommonModes
       可接受的socket將自動(dòng) 繼承相同的運(yùn)行循環(huán)模式就像偵聽socket
       注意:NSRunLoopCommonModes 定義在10.5寨闹,對(duì)于之前的版本可使用 kCFRunLoopCommonModes

      -(NSArray *)runLoopModes
        返回當(dāng)前正在運(yùn)行的循環(huán)模式的AsyncSocket實(shí)例, run loop modes的默認(rèn)設(shè)置是NSDefaultRunLoopMode

      -(NSData *)unreadData;
     一個(gè)錯(cuò)誤的事件君账,在 onSocket:willDisconnectWithError: 將會(huì)被調(diào)用 去讀取留在socket上的任何數(shù)據(jù)

      + (NSData *)CRLFData;   // 0x0D0A

各方法的解析
-(void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
發(fā)生錯(cuò)誤繁堡,socket關(guān)閉,可以在call-back過程調(diào)用"unreadData"去取得socket的最后的數(shù)據(jù)字節(jié)乡数,當(dāng)連接的時(shí)候椭蹄,該委托方法在 onSocket:didAcceptNewSocket: 或者 onSocket:didConnectToHost: 之前調(diào)用
發(fā)生錯(cuò)誤,socket關(guān)閉净赴,可以在call-back過程調(diào)用"unreadData"去取得socket的最后的數(shù)據(jù)字節(jié)绳矩,當(dāng)連接的時(shí)候,該委托方法在 onSocket:didAcceptNewSocket: 或者 onSocket:didConnectToHost: 之前調(diào)用
-(void)onSocketDidDisconnect:(ASyncSocket *)sock;
當(dāng)socket由于或沒有錯(cuò)誤而斷開連接玖翅,如果你想要在斷開連接后release socket翼馆,在此方法工作,而在onSocket:willDisconnectWithError 釋放則不安全
-(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket;
當(dāng)產(chǎn)生一個(gè)socket去處理連接時(shí)調(diào)用金度,此方法會(huì)返回 線程上的run-loop 的新的socket和其應(yīng)處理的委托应媚,如果省略,則使用[NSRunLoop cunrrentRunLoop]
當(dāng)產(chǎn)生一個(gè)socket去處理連接時(shí)調(diào)用猜极,此方法會(huì)返回 線程上的run-loop 的新的socket和其應(yīng)處理的委托中姜,如果省略,則使用[NSRunLoop cunrrentRunLoop]
-(BOOL)onSocketWillConnect:(AsyncSocket *)sock;
-(void)onSocket:(AsyncSocket *)sock didConnectToHost :(NSString *)host port:(UINt16)port;
當(dāng)socket連接正準(zhǔn)備讀和寫的時(shí)候調(diào)用跟伏,host屬性是一個(gè)IP地址扎筒,而不是一個(gè)DNS 名稱
-(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long) tag;
當(dāng)socket已完成所要求的數(shù)據(jù)讀入內(nèi)存時(shí)調(diào)用,如果有錯(cuò)誤則不調(diào)用
-(void)onSocket:(Asyncsocket *)sock didReadPartialDataOfLength:(NSUInteger)partiaLength tag:(long)tag;
當(dāng)一個(gè)socket讀取數(shù)據(jù)酬姆,但尚未完成讀操作的時(shí)候調(diào)用嗜桌,如果使用 readToData: or readToLength: 方法 會(huì)發(fā)生,可以被用來更新進(jìn)度條等東西
-(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
當(dāng)一個(gè)socket已完成請(qǐng)求數(shù)據(jù)的寫入時(shí)候調(diào)用
-(void)onSocket:(AsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag;
當(dāng)一個(gè)socket寫入一些數(shù)據(jù),但還沒有完成整個(gè)寫入時(shí)調(diào)用辞色,它可以用來更新進(jìn)度條等東西
-(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag elapsed:(NSTimeInterval)exapsed bytesDone:(NSUInteger)length
使用讀操作已超時(shí)但還沒完成時(shí)調(diào)用骨宠,此方法允許隨意延遲超時(shí),如果返回一個(gè)正的時(shí)間間隔相满,讀取的超時(shí)將有一定量的擴(kuò)展层亿,如果不實(shí)現(xiàn)這個(gè)方法,或會(huì)像往常一樣返回一個(gè)負(fù)的時(shí)間間隔立美,elapsed參數(shù)是 原超時(shí)的總和匿又,加上先前通過這種方法添加的任何補(bǔ)充, length參數(shù)是 讀操作到目前為止已讀取的字節(jié)數(shù)建蹄, 注意碌更,如果返回正數(shù)的話裕偿,這個(gè)方法可能被一個(gè)單獨(dú)的讀取多次調(diào)用
-(NSTimeInterval)onSocket:(AsyncSocket *)sock shouldTimeoutWriteWithTag:(long)tag elapsed:(NSTimeInterval)elapsed bytesDone:(NSUInteger)length;
如果一個(gè)寫操作已達(dá)到其超時(shí)但還沒完成時(shí)調(diào)用,同上
-(void)onSocketDidSecure:(AsyncSocket *)sock;
在socket成功完成ssl/tls協(xié)商時(shí)調(diào)用痛单,此方法除非你使用提供startTLS方法時(shí)候才調(diào)用嘿棘,
如果ssl/tls是無效的證書,socket將會(huì)立即關(guān)閉旭绒,onSocket:willDisconnectWithError:代理方法竟會(huì)與特定的ssl錯(cuò)誤代碼一起調(diào)用
-(BOOL)canSafelySetDelegate
用來查看在改變它之前鸟妙,是否帶有與當(dāng)前的委托有懸而未決的業(yè)務(wù)(讀/寫)。當(dāng)然挥吵,應(yīng)在安全連接或接受委托之前改變委托
一旦接收或連接方法之一被調(diào)用重父,AsyncSocket實(shí)例會(huì)被鎖定,其他接收/連接方法在沒有先斷開socket不會(huì)被調(diào)用
如果嘗試失敗或超時(shí)忽匈,這些方法要么返回NO 要么調(diào)用 onSocket:willDisconnectWithError: 或 onSockedDidDisconnect
當(dāng)傳入的連接被接受坪郭,AsyncSocket調(diào)用多個(gè)委托方法。這些方法按照時(shí)間順序排列:
1.onSocket:didAcceptNewSocket:
2.onSocket:wantsRunLoopForNewSocket:
3. onSocketWillConnect:

          你的服務(wù)器的代碼將需要保留公認(rèn)的socket(如果要接受它)脉幢,最好的地方是要做到這一點(diǎn)可能在onSocket:didAcceptNewSocket:方法    
         在讀和寫流已經(jīng)為新接受的socket設(shè)置,onSocket:didConnectToHost:port 方法將在適當(dāng)?shù)倪\(yùn)行循環(huán)調(diào)用
         多線程注意嗦锐,如果要想通過實(shí)施onSocket:wantsRunLoopForNewSocket:嫌松,移動(dòng)另一個(gè)新接受的socket去到另一個(gè)循環(huán)的socket。然后奕污,應(yīng)該在調(diào)用讀和寫或者startTLS方法前萎羔,等待直到onSocket:didConnectToHost:port:方法。否則讀和寫時(shí)間原定于不正確的runloop碳默,混亂可能會(huì)隨之而來

         -(BOOL)acceptOnPort:(UInit16)port error:(NSError **)errPtr;
         告訴socket開始聽取和接受制定端口上的連接贾陷,當(dāng)一個(gè)連接到來的時(shí)候,AsyncSocket實(shí)例將調(diào)用各種委托方法嘱根,socket將聽取所有可用的接口(wifi,以太網(wǎng)等)
         -(BOOL)connectToHost:(NSString *)hostname onPort:(UInt16)port error :(NSError **)errPtr;
         連接給定的主機(jī)和端口髓废,主機(jī)hostname可以是域名或者是Ip地址
         -(BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError *)errPtr;
         連接到一個(gè)給定的地址,制定一個(gè)sockaddr結(jié)構(gòu)包裹住一個(gè)NSData對(duì)象,例如该抒,NSData對(duì)象從NSNetService的地址方法返回,如果有一個(gè)現(xiàn)有的sockaddr結(jié)構(gòu)慌洪,可以將它轉(zhuǎn)換到一個(gè)NSData對(duì)象,像這樣:

struct sockaddr sa -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len];
struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len];
-(void)disconnect;
立即斷開凑保,任何未處理的讀或?qū)懚紝⒈粊G棄
如果socket還沒有斷開冈爹,在這個(gè)方法返回之前,onSocketDidDisconnect 委托方法將會(huì)被立即調(diào)用
注意推薦釋放AsyncSocket實(shí)例的方式:
[asyncSocket setDelegate:nil];
[asyncSocket disconnect];
[asyncSocket release];
-(void)disconnectAfterReading;
在已經(jīng)完成了所有懸而未決的讀取時(shí) 斷開,在調(diào)用之后欧引,讀取和寫入方法將無用,socket將斷開 即使仍有待寫入
- (NSString *)connectedHost;
- (UInt16)connectedPort;
- (NSString *)localHost;
- (UInt16)localPort;
返回本地和遠(yuǎn)程主機(jī)和端口給連接的socket频伤,如果沒有連接會(huì)返回nil或0,主機(jī)將會(huì)是一個(gè)IP地址
-(NSData *)connectedAddress
-(NSData *)localAddresss
返回本地和遠(yuǎn)程的地址給連接的socket,指定一個(gè)socketaddr結(jié)構(gòu)包裹在一個(gè)NSData對(duì)象

            readData和writeData方法不會(huì)是block(它們是異步的)
           當(dāng)讀完成 onSocket:didReadData:withTag: 委托方法時(shí)調(diào)用
           當(dāng)寫完成 onSocket:didWriteDataWithTag: 委托方法時(shí)調(diào)用
           可以選擇任何讀/寫操作的超時(shí)設(shè)置(為了不超時(shí)芝此,使用負(fù)時(shí)間間隔憋肖。)
           如果讀/寫操作超時(shí)因痛,相應(yīng)的 onSocket:shouldTimeout...委托方法被調(diào)用去選擇性地允許我們?nèi)パ娱L超時(shí)
           超時(shí)后,onSocket:willDisconnectWithError: 方法被調(diào)用,緊接著是 onSocketDidDisconnect
           tag是為了方便瞬哼,可以使用它作為數(shù)組的索引婚肆、步數(shù)、state id 坐慰、指針等 


        -(void)readDataWithTimeout:(NSTimeInterval)tiemout tag:(long)tag;
          讀取socket上第一次成為可用的字節(jié),如果timeout值是負(fù)數(shù)的较性,讀操作將不使用timeout
        - (void)readDataWithTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInterger)offset tag:(long)tag;
          讀取socket上第一次成為可用的字節(jié)
          字節(jié)將被追加到給定的字節(jié)緩沖區(qū),從給定的偏移量開始
          如果需要结胀,給定的緩沖區(qū)大小將會(huì)自動(dòng)增加
          如果timeout值是負(fù)數(shù)的赞咙,讀操作將不使用timeout
          如果緩沖區(qū)為空,socket會(huì)為我們創(chuàng)建一個(gè)緩沖區(qū)
          如果bufferOffset是大于給定的緩沖區(qū)的長度糟港,該方法將無用攀操,委托將不會(huì)被調(diào)用
          如果你傳遞一個(gè)緩沖區(qū),當(dāng)AsyncSocket在使用它的時(shí)候你不能以任何方式改變它
          完成之后秸抚,onSocket:didReadData:withTag 返回的數(shù)據(jù)將是一個(gè)給定的緩沖區(qū)的子集
          也就是說速和,它將會(huì)被引用到被追加的給定的緩沖區(qū)的字節(jié)
        -(void)readDataToLength:(NSUInterger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;
        讀取給定的字節(jié)數(shù),如果length為0剥汤,方法將無用颠放,委托將不會(huì)被調(diào)用
        -(void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)tiemout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
        讀取給定的字節(jié)數(shù),在給定的偏移開始,字節(jié)將被追加到給定的字節(jié)緩沖區(qū)
        -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
        讀取字節(jié)直到(包括)傳入的作為分隔的"data"參數(shù)
        如果傳遞0或者0長度的數(shù)據(jù)吭敢,"data"參數(shù)碰凶,該方法將無用,委托將不會(huì)被調(diào)用
        從socket讀取一行鹿驼,使用"data"參數(shù)作為行的分隔符 (如HTTP的CRLF)
        注意欲低,此方法不是字符集,因此畜晰,如果一個(gè)分隔符出現(xiàn)砾莱,它自然可以作為進(jìn)行編碼的一部分,讀取將提前結(jié)束
        -(void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout buffer:(NSMutableData *)buffer bufferOffset:(NSUInteger) offset tag:(long)tag;
       讀取字節(jié)直到(包括)傳入的作為分隔的“data”參數(shù)凄鼻,在給定的偏移量開始恤磷,字節(jié)將被追加到給定的字節(jié)緩沖區(qū)。
       從socket讀取一行野宜,使用"data"參數(shù)作為行的分隔符(如HTTP的CRLF)
       -(void)writeData:(NSData *)data withTimeout:(NSTimeInterval) timeout tag:(long)tag;
      將data寫入socket扫步,當(dāng)完成的時(shí)候委托被調(diào)用 
       - (float)progressOfReadReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
       - (float)progressOfWriteReturningTag:(long *)tag bytesDone:(NSUInteger *)done total:(NSUInteger *)total;
       返回當(dāng)前讀或?qū)懙倪M(jìn)度,從0.0 到 1.0 或者 如果沒有讀/寫的時(shí)候返回Nan(使用isNan來檢查)

tag匈子、done河胎、total如果不為空的話,它們將會(huì)被填補(bǔ)

       - (void)startTLS:(NSDictionary *)tlsSettings;
       確保使用ssl/tls連接
       這方法可被隨時(shí)調(diào)用虎敦,tls握手將會(huì)發(fā)生在所有懸而未決的讀/寫完成之后游岳。這緊跟著一個(gè)發(fā)送依賴 StartTLS消息的協(xié)議選項(xiàng)政敢,在排隊(duì)升級(jí)到TLS的同一時(shí)間,而不必等待寫入完成胚迫。在這個(gè)方法被調(diào)用后,任何讀寫計(jì)劃 將會(huì)發(fā)生在安全鏈接
       對(duì)于可能的keys和TLS設(shè)置的值是有據(jù)可查的
       一些可能的keys是:
          * - kCFStreamSSLLevel
          * - kCFStreamSSLAllowsExpiredCertificates
          * - kCFStreamSSLAllowsExpiredRoots
          * - kCFStreamSSLAllowsAnyRoot
          * - kCFStreamSSLValidatesCertificateChain
          * - kCFStreamSSLPeerName
          * - kCFStreamSSLCertificates
          * - kCFStreamSSLIsServer
       如果你傳遞空或者空字典喷户,將使用默認(rèn)的字典
       默認(rèn)設(shè)置將檢查以確保由簽署可信的第三方證書機(jī)構(gòu)和沒有過期的遠(yuǎn)程連接的證書
       然而,它不會(huì)驗(yàn)證證書上的名字访锻,除非你給它一個(gè)名字褪尝,通過kCFStreamSSLPeerName鍵去驗(yàn)證
       這對(duì)安全的影響是重要的理解
       想象一下你正試圖創(chuàng)建一個(gè)到MySecureServer.com的安全連接,但因?yàn)橐粋€(gè)被攻擊的DNS服務(wù)器期犬,所以你的socket被定向到MaliciousServer.com
       如果你只是使用默認(rèn)設(shè)置河哑,MaliciousServer.com 有一個(gè)有效的證書
       默認(rèn)設(shè)置將無法監(jiān)測(cè)到任何問題,因?yàn)樽C書是有效的
      在這個(gè)特殊的情況下龟虎,要妥善保護(hù)你的連接璃谨,應(yīng)設(shè)置kCFStreamSSLPeerName性質(zhì)為MySecureServer.com.
     如果事前你不知道對(duì)等的名字的遠(yuǎn)程主機(jī)(例如,你不確認(rèn)它是domain.com" or "www.domain.com")鲤妥,那么你可以使用默認(rèn)設(shè)置來驗(yàn)證證書佳吞,然后在獲得驗(yàn)證的發(fā)行后使用X509Certificate類來驗(yàn)證,X509Certificate類的CocoaAsyncSocket開源項(xiàng)目的一部分
     -(void)enablePrebuffering
     對(duì)于處理readDataToData請(qǐng)求,數(shù)據(jù)是必須從socket以小增量的方式讀取出來的
     性能通過允許AsyncSocket去一次性讀大塊的數(shù)據(jù)和存儲(chǔ)任何一個(gè)小的內(nèi)部緩沖區(qū)溢出的東西來大大提高
     這被稱為預(yù)緩沖棉安,就好像一些數(shù)據(jù)在你要求它之前就可能被讀取出來
     如果你經(jīng)常使用readDataToData底扳,使用預(yù)緩沖會(huì)有更好的性能,尤其是在iphone上
     默認(rèn)的預(yù)緩沖狀態(tài)是由DEFAULT_PREBUFFERING 定義控制的垂券,強(qiáng)烈建議設(shè)置其為yes
     這方法存在一些預(yù)緩沖需要一些不可預(yù)見的原因被默認(rèn)禁用的情況,這時(shí)羡滑,這種方法存在允許當(dāng)就緒時(shí)菇爪,可輕松啟用預(yù)緩沖
      -(BOOL)moveToRunLoop:(NSRunLoop *)runLoop;
      當(dāng)你創(chuàng)建一個(gè)AsyncSocket,它被添加到當(dāng)前線程runloop
      對(duì)于手動(dòng)創(chuàng)建的socket柒昏,在線程上你打算使用它凳宙,它是最容易簡單的創(chuàng)建的線程上的socket
      當(dāng)一個(gè)新的socket被接受,委托方法 onSocket:wantsRunLoopForNewSocket 會(huì)被調(diào)用 允許你在一個(gè)單獨(dú)的線程上放置socket职祷,這個(gè)工作最好結(jié)合在同一個(gè)線程池設(shè)計(jì)
      如果氏涩,但是,在一個(gè)單獨(dú)的線程上有梆,在之后的時(shí)間是尖,你需要移動(dòng)一個(gè)socket,這個(gè)方法可以用來完成任務(wù)
      此方法必須從 當(dāng)前運(yùn)行的 線程/runloop 的socket 調(diào)用
      注意:此方法調(diào)用后泥耀,所有進(jìn)一步的方法應(yīng)該從給定的runloop上調(diào)用這個(gè)對(duì)象
      此外饺汹,所有委托調(diào)用將會(huì)發(fā)送到給定的runloop

      - (BOOL)setRunLoopModes:(NSArray *)runLoopModes;
      - (BOOL)addRunLoopMode:(NSString *)runLoopMode;
      - (BOOL)removeRunLoopMode:(NSString *)runLoopMode;
       允許你配置 socket 使用的 運(yùn)行循環(huán)模式
       運(yùn)行循環(huán)模式設(shè)置默認(rèn)是NSRunLoopCommonModes
       如果你想你的socket 在其他模式下繼續(xù)操作,你可能需要添加模式 NSModalPanelRunLoopMode 或者 NSEventTrackingRunLoopMode ,或者你可能只想使用 NSRunLoopCommonModes
       可接受的socket將自動(dòng) 繼承相同的運(yùn)行循環(huán)模式就像偵聽socket
       注意:NSRunLoopCommonModes 定義在10.5痰催,對(duì)于之前的版本可使用 kCFRunLoopCommonModes
      -(NSArray *)runLoopModes
        返回當(dāng)前正在運(yùn)行的循環(huán)模式的AsyncSocket實(shí)例兜辞, run loop modes的默認(rèn)設(shè)置是NSDefaultRunLoopMode
      -(NSData *)unreadData;
     一個(gè)錯(cuò)誤的事件迎瞧,在 onSocket:willDisconnectWithError: 將會(huì)被調(diào)用 去讀取留在socket上的任何數(shù)據(jù)
      + (NSData *)CRLFData;   // 0x0D0A
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市逸吵,隨后出現(xiàn)的幾起案子凶硅,更是在濱河造成了極大的恐慌,老刑警劉巖扫皱,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件足绅,死亡現(xiàn)場離奇詭異,居然都是意外死亡啸罢,警方通過查閱死者的電腦和手機(jī)编检,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扰才,“玉大人允懂,你說我怎么就攤上這事●孟唬” “怎么了蕾总?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長琅捏。 經(jīng)常有香客問我生百,道長,這世上最難降的妖魔是什么柄延? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任蚀浆,我火速辦了婚禮,結(jié)果婚禮上搜吧,老公的妹妹穿的比我還像新娘市俊。我一直安慰自己,他們只是感情好滤奈,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布摆昧。 她就那樣靜靜地躺著,像睡著了一般蜒程。 火紅的嫁衣襯著肌膚如雪绅你。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天昭躺,我揣著相機(jī)與錄音忌锯,去河邊找鬼。 笑死领炫,一個(gè)胖子當(dāng)著我的面吹牛汉规,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼针史,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼晶伦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起啄枕,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤婚陪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后频祝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體泌参,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年常空,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了沽一。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡漓糙,死狀恐怖铣缠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情昆禽,我是刑警寧澤蝗蛙,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站醉鳖,受9級(jí)特大地震影響捡硅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜盗棵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一壮韭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧纹因,春花似錦喷屋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽从绘。三九已至寄疏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間僵井,已是汗流浹背陕截。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留批什,地道東北人农曲。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親乳规。 傳聞我的和親對(duì)象是個(gè)殘疾皇子形葬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • iPhone的標(biāo)準(zhǔn)推薦是CFNetwork 庫編程,其封裝好的開源庫是 cocoa AsyncSocket庫暮的,用它...
    Ethan_Struggle閱讀 2,223評(píng)論 2 12
  • iPhone的標(biāo)準(zhǔn)推薦是CFNetwork 庫編程笙以,其封裝好的開源庫是 cocoa AsyncSocket庫,用它...
    夜殤丶夜逝閱讀 4,017評(píng)論 1 23
  • 轉(zhuǎn)載:http://www.cocoachina.com/ios/20170615/19529.html 參考:h...
    F麥子閱讀 3,989評(píng)論 3 2
  • CocoaAsyncSocket支持tcp和udp冻辩。其中: AsyncSocket類是支持TCP的 AsyncUd...
    鄭軍紅閱讀 1,609評(píng)論 0 2
  • 以流的方式處理IM通訊問題好處是無需多次建立連接猖腕,另外消息的網(wǎng)絡(luò)開銷少,而xmpp會(huì)有很多冗余的信息恨闪; 使用開源項(xiàng)...
    sea777777閱讀 2,280評(píng)論 0 8