iOS Kingdom -- 智能开发(Socket篇二)

iOS Kingdom -- 智能开发(Socket篇二)_第1张图片
Bunny
之前在《智能开发(Socket篇一)》的时候已经介绍过怎样用第三方框架 CocoaAsyncSocket 实现 TCP/IP 连接。现在,再介绍一种用原生的输入输出流来实现 socket 连接。

1、实现NSStreamDelegate协议

这个是监听 socket 的连接、数据发送、数据接收以及连接断开的协议
- (void)stream:(NSStream *)aStream
   handleEvent:(NSStreamEvent)eventCode {
    switch (eventCode) {
        case NSStreamEventNone: {
            NSLog(@"NSStreamEventNone");
            break;
        }
        case NSStreamEventOpenCompleted: { 
            // 完成连接
            NSLog(@"NSStreamEventOpenCompleted");
            break;
        }
        case NSStreamEventHasBytesAvailable: {
            // 有数据可读,即有数据从服务器传过来
            NSLog(@"NSStreamEventHasBytesAvailable");
            // 读数据
            [self readData];
            break;
        }
        case NSStreamEventHasSpaceAvailable: {
            // 有数据发送
            NSLog(@"NSStreamEventHasSpaceAvailable");
            break;
        }
        case NSStreamEventErrorOccurred: {
            // 不正常断开连接
            NSLog(@"NSStreamEventErrorOccurred: %@",[aStream streamError]);
            break;
        }
        case NSStreamEventEndEncountered: {
            // 正常断开连接
            NSLog(@"NSStreamEventEndEncountered");
            break;
        }
    }
}

2、定义输入输出流实例变量

这两个变量就相当于架在客户端与服务器间的两条管,一条用于数据流出,另一条用于数据流入
{
    NSOutputStream *_outputStream;
    NSInputStream *_inputStream;
}

3、三次握手建立长连接

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

    // 创建 C 类型输入输出
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;

    // 创建连接
    CFStreamCreatePairWithSocketToHost(NULL,
                                       (__bridge CFStringRef)(ip),
                                       port,
                                       &readStream,
                                       &writeStream);
    // 将 C 类型转成 OC 对象
    _intputStream = (__bridge NSInputStream *)(readStream);
    _outputStream = (__bridge NSOutputStream *)(writeStream);
    // 释放 C 类型输入输出流
    CFRelease(readStream);
    CFRelease(writeStream);

    // 将输入输出流添加到当前运行循环
    [_intputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
                             forMode:NSDefaultRunLoopMode];
    [_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
                             forMode:NSDefaultRunLoopMode];
    // 设置 NSStreamDelegate 监听对象
    _intputStream.delegate = self;
    _outputStream.delegate = self;
    // 打开输入输出监听
    [_intputStream open];
    [_outputStream open];

4、发送数据

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

5、读数据

- (void)readData {
    // 建立一个 1024byte 的缓存区,一次最多可读 1024byte
    uint8_t buff[1024];
    //  len 为实际读到的数据
    NSInteger len =  [_intputStream read:buff
                               maxLength:sizeof(buff)];
    NSData *data = [NSData dataWithBytes:buff
                                  length:len];
}

6、断开连接

    [_intputStream close];
    [_intputStream removeFromRunLoop:[NSRunLoop currentRunLoop]
                             forMode:NSDefaultRunLoopMode];
    [_outputStream close];
    [_outputStream removeFromRunLoop:[NSRunLoop currentRunLoop]
                             forMode:NSDefaultRunLoopMode];

你可能感兴趣的:(iOS Kingdom -- 智能开发(Socket篇二))