CFStream实现socket
1,利用CFStream建立socket连接:
- 建立连接的基本设置并设置代理,通过代理进行监听:
//1,通过Stream创建Socket对连接到主机,第一个值CFAllocatorRef alloc传NULL,可以默认分配内存
//五个参数分别是:分配空间,主机,端口号,输入流,输出流
NSString *host = @"127.0.0.1";//我这里直接连接本机
unsigned int port = 5222;//Openfire的默认端口,我已经安装过Openfire服务器,所以我这里可以连接到这个端口
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)(host), port, &readStream, &writeStream);
//2,把c语言的输入输出流转换成OC的输入输出流,方便后期用代理进行监听
_inputStream = (__bridge NSInputStream *)(readStream);
_outputStream = (__bridge NSOutputStream *)(writeStream);
//3,设置代理就可以进行监听了
_inputStream.delegate = self;
_outputStream.delegate = self;
//4,把输入输出流放到主运行循环中,并打开输入输出流
[_inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[_outputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[_inputStream open];
[_outputStream open];
2,遵守协议后实现监听方法即可监听状态的改变如下:
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{
/*
NSStreamEventNone = 0,
NSStreamEventOpenCompleted = 1UL << 0,//输入输出流打开成功
NSStreamEventHasBytesAvailable = 1UL << 1,//有信息
NSStreamEventHasSpaceAvailable = 1UL << 2,//可以发送信息
NSStreamEventErrorOccurred = 1UL << 3,//连接出错
NSStreamEventEndEncountered = 1UL << 4//连接结束
*/
switch (eventCode) {
case NSStreamEventOpenCompleted:
NSLog(@"输入输出流打开成功");
break;
case NSStreamEventHasBytesAvailable:{
NSLog(@"有信息");
uint8_t buf[1024];//建立一个1024字节的缓冲区
//返回信息的实际字节长度
NSInteger length = [_inputStream read:buf maxLength:sizeof(buf)];
//把字节转换成字符串
NSData *data = [NSData dataWithBytes:buf length:length];
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"接收到消息----%@------%@",aStream, str);
break;
}
case NSStreamEventHasSpaceAvailable:
NSLog(@"可以发送信息");
break;
case NSStreamEventErrorOccurred:
NSLog(@"连接出错");
break;
case NSStreamEventEndEncountered:
NSLog(@"连接结束");
break;
default:
break;
}
}
3,数据操作,由于我这里没有服务器,所以只是简单的演示一下:
//1,发送用户名过去,这里需要按照xmpp通讯协议的格式写上正确的xml格式发送才可以,我这里写的好像不对,所以没有返回数据
NSString *userName = @"admin";
NSData *data = [userName dataUsingEncoding:NSUTF8StringEncoding];
[_outputStream write:data.bytes maxLength:data.length];
GCDAsyncSocket实现socket
1,建立连接,设置代理等
//1,建立socket
_asynSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
NSString *host = @"127.0.0.1";
uint16_t port = 5222;
NSError *error;
[_asynSocket connectToHost:host onPort:port error:&error];
if (error) {
NSLog(@"%@",error);
}else{
NSLog(@"连接正确");
}
2,遵守协议,实现代理方法等
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port{
NSLog(@"连接主机成功");
}
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{
NSLog(@"数据发送成功---%ld",tag);
//需要在发送成功后手动调用readData方法才能在接受的代理方法中正确接受到数据
[_asynSocket readDataWithTimeout:-1 tag:tag];
}
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
NSLog(@"接受到数据---%@",data);
}
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
NSLog(@"与主机断开连接---%@",err);
}
3,读写数据等
//读写数据
NSData *data = [@"zhangdanfeng" dataUsingEncoding:NSUTF8StringEncoding];
[_asynSocket writeData:data withTimeout:-1 tag:100];