定义变量
//定义变量
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]];
至此,建立连接、异常检查、读取数据、发送数据的基本过程已具备