《iOS学习笔记—OC中的Socket通信》

来源:互联网 发布:android 仿照淘宝排序 编辑:程序博客网 时间:2024/06/07 16:53

1、OC原生的Socket通信

现在很多客户端和服务器之间的交互都是通过JSON或者XML进行的短连接;

Socket允许使用长连接,允许应用程序运行在异步模式(提高效率),只有在需要的时候才接收数据
在iOS中以NSStream(流)来发送和接收数据,可以设置流的代理,对流状态的变化做出相应(连接建立、接收到数据、连接关闭
2、OC中Socket主要用到的类
1)NSStream:数据流的父类,用于定义抽象特性,例如:打开、关闭代理,NSStream继承自CFStream(Core Foundation)
2)NSInputStream:NSStream的子类,用于读取输入
3)NSOutputStream:NSSTream的子类,用于写输出

下面是开发步骤:
1.网络连接设置
  1).设置网络连接,绑定到主机和端口
  2).设置输入流和输出流的代理,监听数据流的状态
  3).将输入输出流添加至运行循环
  4).打开输入流和输出流
// 输入流,用来读取服务器返回的字节NSInputStream *inputStream;// 输出流,用于给服务器发送字节NSOutputStream *outputStream;

提示:在OC中使用Socket需要用到CoreFoundation的一些流技术,创建流的时候需要用CFXXX等创建,然后在转换为NSXXX

下面是跟服务器建建立链接的方法

// 建立与服务器的连接-(void)connectToServer:(NSString *)host port:(NSInteger)port{// 创建CF下的读入流CFReadStreamRef readStream;// 创建CF下的写出流CFWriteStreamRef writeStream;// 创建流CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)(host), port, &readStream, &writeStream);// 将CFXXX流和NSXXX流建立对应关系inputStream = (__bridge NSInputStream *)(readStream);outputStream = (__bridge NSOutputStream *)(writeStream);// 设置通信过程中的代理inputStream.delegate = self;outputStream.delegate = self;// 将流对象添加到主运行循环(如果不加到主循环,Socket流是不会工作的)[inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];[outputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];// 打开流[inputStream open];[outputStream open];}


然后让你的类遵守NSStreamDelegate协议
并且实现下面的方法进行监听

 
-(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{    NSLog(@"%u",eventCode);        switch (eventCode) {        case NSStreamEventOpenCompleted:            NSLog(@"连接完成");            break;        case NSStreamEventHasBytesAvailable:        {NSLog(@"有刻度字节");            uint8_t buffer[10];            NSMutableString *mstr = [NSMutableString string];            int len;// = [inputStream read:buffer maxLength:sizeof(buffer)];            do{                len =  [inputStream read:buffer maxLength:sizeof(buffer)];                NSString *s = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding];                [mstr appendString:s];            }while (len == sizeof(buffer));                       NSLog(@"====%@====",mstr);        }            break;        case NSStreamEventHasSpaceAvailable:            NSLog(@"可以写入数据");            break;        case NSStreamEventErrorOccurred:            NSLog(@"发生错误");            break;        case NSStreamEventEndEncountered:            NSLog(@"流结束");            // 做善后工作            // 关闭流的同时,将流从主运行循环中删除            [aStream close];            [aStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];        default:            break;    }  }
【提示】要记得流关闭的时候要从主循环中移除。
 
原创粉丝点击