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];