iOS網路編程實踐–NSStream實現TCP Socket iPhone用戶端

來源:互聯網
上載者:User

用戶端我們使用iPhone應用程式,畫面比較簡單。點擊發送按鈕,給伺服器發送一些字串過去。點擊接收按鈕就會從伺服器讀取一些字串,並且顯示在畫面上。

 

有關用戶端應用的UI部分不再介紹了,我們直接看代碼部分,Socket用戶端可以採用CFStream或NSStream實現,CFStream 實現方式與伺服器端基本一樣。為了給讀者介紹更多的知識,本例我們採用NSStream實現。NSStream實現採用Objective-C語言,一些 物件導向的類。

下面我們看看用戶端視圖控制器ViewController.h

#import <CoreFoundation/CoreFoundation.h>#include <sys/socket.h>#include <netinet/in.h> #define PORT 9000 @interface ViewController : UIViewController<NSStreamDelegate>{int flag ; //操作標誌 0為發送 1為接收} @property (nonatomic, retain) NSInputStream *inputStream;@property (nonatomic, retain) NSOutputStream *outputStream; @property (weak, nonatomic) IBOutlet UILabel *message; - (IBAction)sendData:(id)sender;- (IBAction)receiveData:(id)sender; @end

 

定義屬性inputStream和outputStream,它們輸入資料流NSInputStream和輸出資料流NSOutputStream類。它們與伺服器CFStream實現中的輸入資料流CFReadStreamRef和輸出資料流CFWriteStreamRef對應的。

視圖控制器ViewController.m的初始化網路方法initNetworkCommunication代碼:

- (void)initNetworkCommunication{CFReadStreamRef readStream;CFWriteStreamRef writeStream;CFStreamCreatePairWithSocketToHost(NULL,(CFStringRef)@”192.168.1.103″, PORT, &readStream, &writeStream);   ①_inputStream = (__bridge_transfer NSInputStream *)readStream; ②_outputStream = (__bridge_transfer NSOutputStream*)writeStream;  ③[_inputStream setDelegate:self];  ④[_outputStream setDelegate:self];  ⑤[_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]forMode:NSDefaultRunLoopMode]; ⑥[_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]forMode:NSDefaultRunLoopMode];  ⑦[_inputStream open];  ⑧[_outputStream open];  ⑨}

 

 

點擊發送和接收按鈕觸發的方法如下:

/* 點擊發送按鈕  */- (IBAction)sendData:(id)sender {flag = 0;[self initNetworkCommunication];}/* 點擊接收按鈕  */- (IBAction)receiveData:(id)sender {flag = 1;[self initNetworkCommunication];}

 

它們都調用initNetworkCommunication方法,並設定作業標識flag,如果flag為0發送資料,flag為1接收資料。

流的狀態的變化觸發很多事件,並回調NSStreamDelegate協議中定義的方法stream:handleEvent:,其代碼如下:

-(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {NSString *event;switch (streamEvent) {case NSStreamEventNone:event = @”NSStreamEventNone”;break;case NSStreamEventOpenCompleted:event = @”NSStreamEventOpenCompleted”;break;case NSStreamEventHasBytesAvailable:event = @”NSStreamEventHasBytesAvailable”;if (flag ==1 && theStream == _inputStream) {NSMutableData *input = [[NSMutableData alloc] init];uint8_t buffer[1024];  ①int len;while([_inputStream hasBytesAvailable]) ②{len = [_inputStream read:buffer maxLength:sizeof(buffer)];  ③if (len > 0){[input appendBytes:buffer length:len];}}NSString *resultstring = [[NSString alloc]initWithData:input encoding:NSUTF8StringEncoding];NSLog(@”接收:%@”,resultstring);_message.text = resultstring;}break;case NSStreamEventHasSpaceAvailable:event = @”NSStreamEventHasSpaceAvailable”;if (flag ==0 && theStream == _outputStream) {//輸出UInt8 buff[] = ”Hello Server!”; ④[_outputStream write:buff maxLength: strlen((const char*)buff)+1]; ⑤//關閉輸出資料流[_outputStream close];}break;case NSStreamEventErrorOccurred:event = @”NSStreamEventErrorOccurred”;[self close]; ⑥break;case NSStreamEventEndEncountered:event = @”NSStreamEventEndEncountered”;NSLog(@”Error:%d:%@”,[[theStream streamError] code],[[theStream streamError] localizedDescription]);break;default:[self close];  ⑦event = @”Unknown”;break;}NSLog(@”event——%@”,event);}

 

在讀取資料分支(NSStreamEventHasBytesAvailable)中,代碼第①行為讀取資料準備緩衝區,本例中設定的是1024個位元組,這個大小會對流的讀取有很多的影響。第②行代碼使用hasBytesAvailable方法判斷是否流有資料可以讀,如果有可讀資料就進行迴圈讀取。第③行代碼使用流的read:maxLength:方法讀取資料到緩衝區,第1個參數是緩衝區對象buffer,第2個參數是讀取的緩衝區的位元組長度。

在寫入資料分支(NSStreamEventHasSpaceAvailable)中,代碼第④行是要寫入的資料,第⑤行代碼 [_outputStream write:buff maxLength: strlen((const char*)buff)+1]是寫如資料方 法。

第⑥和第⑦行代碼[self close]調用close方法關閉,close方法代碼如下:

-(void)close{[_outputStream close];[_outputStream removeFromRunLoop:[NSRunLoop currentRunLoop]forMode:NSDefaultRunLoopMode];[_outputStream setDelegate:nil];[_inputStream close];[_inputStream removeFromRunLoop:[NSRunLoop currentRunLoop]forMode:NSDefaultRunLoopMode];[_inputStream setDelegate:nil];}

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.