Bunny
之前在<a href="http://www.lxweimin.com/p/f0b9a76f9ae4">《智能開發(fā)(Socket篇一)》</a>的時(shí)候已經(jīng)介紹過怎樣用第三方框架 CocoaAsyncSocket
實(shí)現(xiàn) TCP/IP 連接。現(xiàn)在,再介紹一種用原生的輸入輸出流來實(shí)現(xiàn) socket 連接。
1、實(shí)現(xiàn)NSStreamDelegate
協(xié)議
這個(gè)是監(jiān)聽 socket 的連接、數(shù)據(jù)發(fā)送、數(shù)據(jù)接收以及連接斷開的協(xié)議
- (void)stream:(NSStream *)aStream
handleEvent:(NSStreamEvent)eventCode {
switch (eventCode) {
case NSStreamEventNone: {
NSLog(@"NSStreamEventNone");
break;
}
case NSStreamEventOpenCompleted: {
// 完成連接
NSLog(@"NSStreamEventOpenCompleted");
break;
}
case NSStreamEventHasBytesAvailable: {
// 有數(shù)據(jù)可讀,即有數(shù)據(jù)從服務(wù)器傳過來
NSLog(@"NSStreamEventHasBytesAvailable");
// 讀數(shù)據(jù)
[self readData];
break;
}
case NSStreamEventHasSpaceAvailable: {
// 有數(shù)據(jù)發(fā)送
NSLog(@"NSStreamEventHasSpaceAvailable");
break;
}
case NSStreamEventErrorOccurred: {
// 不正常斷開連接
NSLog(@"NSStreamEventErrorOccurred: %@",[aStream streamError]);
break;
}
case NSStreamEventEndEncountered: {
// 正常斷開連接
NSLog(@"NSStreamEventEndEncountered");
break;
}
}
}
2、定義輸入輸出流實(shí)例變量
這兩個(gè)變量就相當(dāng)于架在客戶端與服務(wù)器間的兩條管,一條用于數(shù)據(jù)流出,另一條用于數(shù)據(jù)流入
{
NSOutputStream *_outputStream;
NSInputStream *_inputStream;
}
3、三次握手建立長(zhǎng)連接
NSString *ip = @"127.0.0.1";
int port = 8080;
// 創(chuàng)建 C 類型輸入輸出
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
// 創(chuàng)建連接
CFStreamCreatePairWithSocketToHost(NULL,
(__bridge CFStringRef)(ip),
port,
&readStream,
&writeStream);
// 將 C 類型轉(zhuǎn)成 OC 對(duì)象
_intputStream = (__bridge NSInputStream *)(readStream);
_outputStream = (__bridge NSOutputStream *)(writeStream);
// 釋放 C 類型輸入輸出流
CFRelease(readStream);
CFRelease(writeStream);
// 將輸入輸出流添加到當(dāng)前運(yùn)行循環(huán)
[_intputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
// 設(shè)置 NSStreamDelegate 監(jiān)聽對(duì)象
_intputStream.delegate = self;
_outputStream.delegate = self;
// 打開輸入輸出監(jiān)聽
[_intputStream open];
[_outputStream open];
4、發(fā)送數(shù)據(jù)
NSData *data = [NSData dataWithBytes:"\x0a\x0d"
length:2];
[_outputStream write:data.bytes
maxLength:data.length];
5、讀數(shù)據(jù)
- (void)readData {
// 建立一個(gè) 1024byte 的緩存區(qū),一次最多可讀 1024byte
uint8_t buff[1024];
// len 為實(shí)際讀到的數(shù)據(jù)
NSInteger len = [_intputStream read:buff
maxLength:sizeof(buff)];
NSData *data = [NSData dataWithBytes:buff
length:len];
}
6、斷開連接
[_intputStream close];
[_intputStream removeFromRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[_outputStream close];
[_outputStream removeFromRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];