iOS中NSStream實現(xiàn)發(fā)送和接受數(shù)據(jù)

一究抓、基本概念
在iOS中以NSStream(流)來發(fā)送和接收數(shù)據(jù),可以設(shè)置流的代理,對流狀態(tài)的變化做出相應(yīng)啥刻。
1連接建立
2接收到數(shù)據(jù)
3連接關(guān)閉
NSStream:數(shù)據(jù)流的父類,用于定義抽象特性咪笑,例如:打開可帽、關(guān)閉代理,NSStream繼承自CFStream(CoreFoundation)
NSInputStream:NSStream的子類窗怒,用于讀取輸入
NSOutputStream:NSSTream的子類映跟,用于寫輸出

二、開發(fā)步驟
1扬虚、網(wǎng)絡(luò)連接設(shè)置
設(shè)置網(wǎng)絡(luò)連接努隙,綁定到主機(jī)和端口
設(shè)置輸入流和輸出流的代理,監(jiān)聽數(shù)據(jù)流的狀態(tài)
將輸入輸出流添加至運(yùn)行循環(huán)
打開輸入流和輸出流
2孔轴、發(fā)送消息給服務(wù)器
3剃法、有可讀取字節(jié)時,讀取服務(wù)器返回的內(nèi)容
4、到達(dá)流末尾時贷洲,關(guān)閉流收厨,同時并從主運(yùn)行循環(huán)中刪除

#import "ViewController.h"

@interface ViewController ()<NSStreamDelegate>{
    NSInputStream *_inputStream;
    NSOutputStream *_outputSteam;
}

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}


- (IBAction)connectToServer:(id)sender {
    //ios里實現(xiàn)sokcet的連接,使用C語言
    
    // 1.與服務(wù)器通過三次握手建立連接
    NSString *host = @"127.0.0.1";
    int port = 12345;
    
    // 2.定義輸入輸出流
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    
    // 3.分配輸入輸出流的內(nèi)存空間
    CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, port, &readStream, &writeStream);
    
    // 4.把C語言的輸入輸出流轉(zhuǎn)成OC對象
    _inputStream = (__bridge NSInputStream *)readStream;
    _outputSteam = (__bridge NSOutputStream *)(writeStream);
    
    // 5.設(shè)置代理,監(jiān)聽數(shù)據(jù)接收的狀態(tài)
    _outputSteam.delegate = self;
    _inputStream.delegate = self;
    
    // 把輸入輸入流添加到主運(yùn)行循環(huán)(RunLoop)
    // 主運(yùn)行循環(huán)是監(jiān)聽網(wǎng)絡(luò)狀態(tài)
    [_outputSteam scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    [_inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    
    
    // 6.打開輸入輸出流
    [_inputStream open];
    [_outputSteam open];
}


//代理的回調(diào)是在主線程
//NSLog(@"%@",[NSThread currentThread]);
-(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{

//    NSStreamEventOpenCompleted = 1UL << 0,
//    NSStreamEventHasBytesAvailable = 1UL << 1,
//    NSStreamEventHasSpaceAvailable = 1UL << 2,
//    NSStreamEventErrorOccurred = 1UL << 3,
//    NSStreamEventEndEncountered = 1UL << 4
    
    switch (eventCode) {
        case NSStreamEventOpenCompleted:
            NSLog(@"%@",aStream);
            NSLog(@"成功連接建立优构,形成輸入輸出流的傳輸通道");
            break;
            
        case NSStreamEventHasBytesAvailable:
            NSLog(@"有數(shù)據(jù)可讀");
            [self readData];
            break;
            
        case NSStreamEventHasSpaceAvailable:
            NSLog(@"可以發(fā)送數(shù)據(jù)");
            break;
            
         case NSStreamEventErrorOccurred:
            NSLog(@"有錯誤發(fā)生诵叁,連接失敗");
            break;
            
         case NSStreamEventEndEncountered:
            NSLog(@"正常的斷開連接");
            //把輸入輸入流關(guān)閉,而還要從主運(yùn)行循環(huán)移除
            [_inputStream close];
            [_outputSteam close];
            [_inputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
            [_outputSteam removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

            break;
        default:
            break;
    }

}

- (IBAction)loginBtnClick:(id)sender {
    //發(fā)送登錄請求 使用輸出流
    
    //拼接登錄的指令 iam:zhangsan
    NSString *loginStr = @"iam:zhangsan";
    
    //uint8_t * 字符數(shù)組
    NSData *data = [loginStr dataUsingEncoding:NSUTF8StringEncoding];
    [_outputSteam write:data.bytes maxLength:data.length];
    
}


#pragma mark 讀取服務(wù)器返回的數(shù)據(jù)
-(void)readData{
    
    //定義緩沖區(qū) 這個緩沖區(qū)只能存儲1024字節(jié)
    uint8_t buf[1024];
    
    // 讀取數(shù)據(jù)
    // len為從服務(wù)器讀取到的實際字節(jié)數(shù)
    NSInteger len = [_inputStream read:buf maxLength:sizeof(buf)];
    
    // 把緩沖區(qū)里的實現(xiàn)字節(jié)數(shù)轉(zhuǎn)成字符串
    NSString *receiverStr = [[NSString alloc] initWithBytes:buf length:len encoding:NSUTF8StringEncoding];
    NSLog(@"%@",receiverStr);

}
@end

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末钦椭,一起剝皮案震驚了整個濱河市拧额,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌彪腔,老刑警劉巖侥锦,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異德挣,居然都是意外死亡恭垦,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進(jìn)店門格嗅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來番挺,“玉大人,你說我怎么就攤上這事屯掖⌒兀” “怎么了?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵贴铜,是天一觀的道長粪摘。 經(jīng)常有香客問我,道長绍坝,這世上最難降的妖魔是什么赶熟? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮陷嘴,結(jié)果婚禮上映砖,老公的妹妹穿的比我還像新娘。我一直安慰自己灾挨,他們只是感情好邑退,可當(dāng)我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著劳澄,像睡著了一般地技。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上秒拔,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天莫矗,我揣著相機(jī)與錄音,去河邊找鬼。 笑死作谚,一個胖子當(dāng)著我的面吹牛三娩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播妹懒,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼雀监,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了眨唬?” 一聲冷哼從身側(cè)響起会前,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎匾竿,沒想到半個月后瓦宜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡岭妖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年歉提,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片区转。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖版扩,靈堂內(nèi)的尸體忽然破棺而出废离,到底是詐尸還是另有隱情,我是刑警寧澤礁芦,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布蜻韭,位于F島的核電站,受9級特大地震影響柿扣,放射性物質(zhì)發(fā)生泄漏肖方。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一未状、第九天 我趴在偏房一處隱蔽的房頂上張望俯画。 院中可真熱鬧,春花似錦司草、人聲如沸艰垂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽猜憎。三九已至,卻和暖如春搔课,著一層夾襖步出監(jiān)牢的瞬間胰柑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留柬讨,地道東北人崩瓤。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像姐浮,于是被迫代替她去往敵國和親谷遂。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容