iOS Kingdom -- 智能開(kāi)發(fā)(Socket篇二)

Bunny
之前在<a href="http://www.itdecent.cn/p/f0b9a76f9ae4">《智能開(kāi)發(fā)(Socket篇一)》</a>的時(shí)候已經(jīng)介紹過(guò)怎樣用第三方框架 CocoaAsyncSocket 實(shí)現(xiàn) TCP/IP 連接?,F(xiàn)在,再介紹一種用原生的輸入輸出流來(lái)實(shí)現(xiàn) socket 連接。

1、實(shí)現(xiàn)NSStreamDelegate協(xié)議

這個(gè)是監(jiān)聽(tīng) socket 的連接、數(shù)據(jù)發(fā)送、數(shù)據(jù)接收以及連接斷開(kāi)的協(xié)議
- (void)stream:(NSStream *)aStream
   handleEvent:(NSStreamEvent)eventCode {
    switch (eventCode) {
        case NSStreamEventNone: {
            NSLog(@"NSStreamEventNone");
            break;
        }
        case NSStreamEventOpenCompleted: { 
            // 完成連接
            NSLog(@"NSStreamEventOpenCompleted");
            break;
        }
        case NSStreamEventHasBytesAvailable: {
            // 有數(shù)據(jù)可讀,即有數(shù)據(jù)從服務(wù)器傳過(guò)來(lái)
            NSLog(@"NSStreamEventHasBytesAvailable");
            // 讀數(shù)據(jù)
            [self readData];
            break;
        }
        case NSStreamEventHasSpaceAvailable: {
            // 有數(shù)據(jù)發(fā)送
            NSLog(@"NSStreamEventHasSpaceAvailable");
            break;
        }
        case NSStreamEventErrorOccurred: {
            // 不正常斷開(kāi)連接
            NSLog(@"NSStreamEventErrorOccurred: %@",[aStream streamError]);
            break;
        }
        case NSStreamEventEndEncountered: {
            // 正常斷開(kāi)連接
            NSLog(@"NSStreamEventEndEncountered");
            break;
        }
    }
}

2、定義輸入輸出流實(shí)例變量

這兩個(gè)變量就相當(dāng)于架在客戶端與服務(wù)器間的兩條管,一條用于數(shù)據(jù)流出,另一條用于數(shù)據(jù)流入
{
    NSOutputStream *_outputStream;
    NSInputStream *_inputStream;
}

3、三次握手建立長(zhǎng)連接

    NSString *ip = @"127.0.0.1";
    int port = 8080;

    // 創(chuàng)建 C 類(lèi)型輸入輸出
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;

    // 創(chuàng)建連接
    CFStreamCreatePairWithSocketToHost(NULL,
                                       (__bridge CFStringRef)(ip),
                                       port,
                                       &readStream,
                                       &writeStream);
    // 將 C 類(lèi)型轉(zhuǎn)成 OC 對(duì)象
    _intputStream = (__bridge NSInputStream *)(readStream);
    _outputStream = (__bridge NSOutputStream *)(writeStream);
    // 釋放 C 類(lèi)型輸入輸出流
    CFRelease(readStream);
    CFRelease(writeStream);

    // 將輸入輸出流添加到當(dāng)前運(yùn)行循環(huán)
    [_intputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
                             forMode:NSDefaultRunLoopMode];
    [_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
                             forMode:NSDefaultRunLoopMode];
    // 設(shè)置 NSStreamDelegate 監(jiān)聽(tīng)對(duì)象
    _intputStream.delegate = self;
    _outputStream.delegate = self;
    // 打開(kāi)輸入輸出監(jiān)聽(tīng)
    [_intputStream open];
    [_outputStream open];

4、發(fā)送數(shù)據(jù)

    NSData *data = [NSData dataWithBytes:"\x0a\x0d"
                                  length:2];
    [_outputStream write:data.bytes
            maxLength:data.length];

5、讀數(shù)據(jù)

- (void)readData {
    // 建立一個(gè) 1024byte 的緩存區(qū),一次最多可讀 1024byte
    uint8_t buff[1024];
    //  len 為實(shí)際讀到的數(shù)據(jù)
    NSInteger len =  [_intputStream read:buff
                               maxLength:sizeof(buff)];
    NSData *data = [NSData dataWithBytes:buff
                                  length:len];
}

6、斷開(kāi)連接

    [_intputStream close];
    [_intputStream removeFromRunLoop:[NSRunLoop currentRunLoop]
                             forMode:NSDefaultRunLoopMode];
    [_outputStream close];
    [_outputStream removeFromRunLoop:[NSRunLoop currentRunLoop]
                             forMode:NSDefaultRunLoopMode];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容