NSStream创建Socket连接

定义变量 

//定义变量
    NSInputStream *inputStream; //数据从文件/设备到app内存叫做input stream
    NSOutputStream *outputStream; //数据从app 内存到文件/设备叫做output stream
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    
    NSString *ip;//socket的ip
    UInt32 port;//socket的port
    uint8_t buf[READ_BUFFER_LENGTH]; //buffer缓存定义
 

创建连接

NSStream 的所有状态Enum值定义:

typedef NS_ENUM(NSUInteger, NSStreamStatus) {
    NSStreamStatusNotOpen = 0,
    NSStreamStatusOpening = 1,
    NSStreamStatusOpen = 2,
    NSStreamStatusReading = 3,
    NSStreamStatusWriting = 4,
    NSStreamStatusAtEnd = 5,
    NSStreamStatusClosed = 6,
    NSStreamStatusError = 7
};

NSStream建立连接的过程:

    ip = @"192.168.1.1";
    port = @8000;
    
    // CFStream中的方法
    CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef)ip, port, &readStream, &writeStream);
    
    //CFWriteStreamClose(writeStream); 
    //CFReadStreamClose(readStream);
    if (readStream && writeStream)
    {
        if(!CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue) ||
        !CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue))
            return connectError;
        inputStream = (__bridge_transfer NSInputStream *)readStream;
        [inputStream setDelegate:self];
        //设置读取数据的代理,相应NSStream的代理方法
        outputStream = (__bridge_transfer NSOutputStream *)writeStream;
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            @autoreleasepool
            {
                [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
                [inputStream open];
                [outputStream open];
                [[NSRunLoop currentRunLoop] run];
            }
        });
        usleep(10000);
        if ([inputStream streamStatus]!=NSStreamStatusOpen){
            //建立连接失败的处理,可以冲洗连接或者报告错误。。。。。
        }
        if ([outputStream streamStatus]!=NSStreamStatusOpen){
            //建立连接失败的处理,可以冲洗连接或者报告错误。。。。。
        }
 /*
打开操作完毕,此后可以通过检查stream的状态来检测是否已经建立连接
通常情况下,中间应该有一定的微小延迟,如果立即检查状态,可能在stream还没建立socket连接时查询到错误状态
*/
    }
    else
    {
        return connectError;
    }
    }

读取数据的代理方法实现

delegate定义了一个唯一的代理方法如下:

@protocol NSStreamDelegate <NSObject>
@optional
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode;
@end

NSStreamEvent所定义的所有状态:

typedef NS_OPTIONS(NSUInteger, NSStreamEvent) {
    NSStreamEventNone = 0,
    NSStreamEventOpenCompleted = 1UL << 0,
    NSStreamEventHasBytesAvailable = 1UL << 1,
    NSStreamEventHasSpaceAvailable = 1UL << 2,
    NSStreamEventErrorOccurred = 1UL << 3,
    NSStreamEventEndEncountered = 1UL << 4
};

数据的转化方式:
1. 字符串转Data

NSString * str =@"str"; 
NSData *data =[str dataUsingEncoding:NSUTF8StringEncoding];

2.NSData 转NSString

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

3.data 转char

NSData *data; 
char * haha=[data bytes]; 

4. char 转data 

byte * byteData = malloc(sizeof(byte)*16); 
NSData *content=[NSData dataWithBytes:byteData length:16];

 5、代理方法读取的内容:

-(void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode {
    switch(eventCode)
    {
        case NSStreamEventHasBytesAvailable:
        {
            NSInteger len = [(NSInputStream *)stream read:self->buf maxLength:READ_BUFFER_LENGTH];
            if (len > READ_BUFFER_LENGTH){
                //此时表示所读取到的数据还没填满我们设置的buffer 
                //可不做处理,或者以某些标识符为间隔做特殊处理
            }
            else
            {
                NSMutableData *data = [[NSMutableData alloc] initWithBytes:(const void *)self->buf length:len];//将byte数据转化为NSData,可调用其他方法处理之
                NSString *receivedResult = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]//NSData到NSString
                NSLog(@"received Result:%@",receivedResult);
                memset(self->buf, 0, len*sizeof(uint8_t));//清空处理过的数据
            }
            break;
        }
        case NSStreamEventErrorOccurred:
        {
            //端口有异常,在此情况下应该检查端口的连接情况,
            //如果发现是连接问题,应该重新连接
            break;
        }
        case NSStreamEventEndEncountered:
        {
            
            break;
        }
        case NSStreamEventHasSpaceAvailable:
        default:
            break;
    }
}

写入数据的方法

//原始定义
//- (NSInteger)write:(const uint8_t *)buffer maxLength:(NSUInteger)len;
// writes the bytes from the specified buffer to the stream up to len bytes. Returns the number of bytes actually written.

[outputStream write:[data bytes] maxLength:[data length]];

至此,建立连接、异常检查、读取数据、发送数据的基本过程已具备

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

auspark

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值