亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

iOS網絡編程實踐--NSStream實現TCP Socket iPhone客戶端

發布時間:2020-06-15 17:25:46 來源:網絡 閱讀:3688 作者:tony關東升 欄目:移動開發

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

 

iOS網絡編程實踐--NSStream實現TCP Socket iPhone客戶端

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

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

 

  1. #import <CoreFoundation/CoreFoundation.h> 
  2.  
  3. #include <sys/socket.h> 
  4.  
  5. #include <netinet/in.h> 
  6.  
  7.   
  8.  
  9. #define PORT 9000 
  10.  
  11.   
  12.  
  13. @interface ViewController : UIViewController<NSStreamDelegate> 
  14.  
  15.  
  16. int flag ; //操作標志 0為發送 1為接收 
  17.  
  18.  
  19.   
  20.  
  21. @property (nonatomic, retain) NSInputStream *inputStream; 
  22.  
  23. @property (nonatomic, retain) NSOutputStream *outputStream; 
  24.  
  25.   
  26.  
  27. @property (weak, nonatomic) IBOutlet UILabel *message; 
  28.  
  29.   
  30.  
  31. - (IBAction)sendData:(id)sender; 
  32.  
  33. - (IBAction)receiveData:(id)sender; 
  34.  
  35.   
  36.  
  37. @end 

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

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

 

  1. - (void)initNetworkCommunication 
  2.  
  3.  
  4. CFReadStreamRef readStream; 
  5.  
  6. CFWriteStreamRef writeStream; 
  7.  
  8. CFStreamCreatePairWithSocketToHost(NULL, 
  9.  
  10. (CFStringRef)@”192.168.1.103″, PORT, &readStream, &writeStream);   ① 
  11.  
  12. _inputStream = (__bridge_transfer NSInputStream *)readStream; ② 
  13.  
  14. _outputStream = (__bridge_transfer NSOutputStream*)writeStream;  ③ 
  15.  
  16. [_inputStream setDelegate:self];  ④ 
  17.  
  18. [_outputStream setDelegate:self];  ⑤ 
  19.  
  20. [_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] 
  21.  
  22. forMode:NSDefaultRunLoopMode]; ⑥ 
  23.  
  24. [_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] 
  25.  
  26. forMode:NSDefaultRunLoopMode];  ⑦ 
  27.  
  28. [_inputStream open];  ⑧ 
  29.  
  30. [_outputStream open];  ⑨ 
  31.  

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

 

  1. /* 點擊發送按鈕  */ 
  2.  
  3. - (IBAction)sendData:(id)sender { 
  4.  
  5. flag = 0; 
  6.  
  7. [self initNetworkCommunication]; 
  8.  
  9.  
  10. /* 點擊接收按鈕  */ 
  11.  
  12. - (IBAction)receiveData:(id)sender { 
  13.  
  14. flag = 1; 
  15.  
  16. [self initNetworkCommunication]; 
  17.  

它們都調用initNetworkCommunication方法,并設置操作標識flag,如果flag0發送數據,flag1接收數據。

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

 

  1. -(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent { 
  2.  
  3. NSString *event; 
  4.  
  5. switch (streamEvent) { 
  6.  
  7. case NSStreamEventNone: 
  8.  
  9. event = @”NSStreamEventNone”; 
  10.  
  11. break
  12.  
  13. case NSStreamEventOpenCompleted: 
  14.  
  15. event = @”NSStreamEventOpenCompleted”; 
  16.  
  17. break
  18.  
  19. case NSStreamEventHasBytesAvailable: 
  20.  
  21. event = @”NSStreamEventHasBytesAvailable”; 
  22.  
  23. if (flag ==1 && theStream == _inputStream) { 
  24.  
  25. NSMutableData *input = [[NSMutableData alloc] init]; 
  26.  
  27. uint8_t buffer[1024];  ① 
  28.  
  29. int len; 
  30.  
  31. while([_inputStream hasBytesAvailable]) ② 
  32.  
  33.  
  34. len = [_inputStream read:buffer maxLength:sizeof(buffer)];  ③ 
  35.  
  36. if (len > 0) 
  37.  
  38.  
  39. [input appendBytes:buffer length:len]; 
  40.  
  41.  
  42.  
  43. NSString *resultstring = [[NSString alloc] 
  44.  
  45. initWithData:input encoding:NSUTF8StringEncoding]; 
  46.  
  47. NSLog(@”接收:%@”,resultstring); 
  48.  
  49. _message.text = resultstring; 
  50.  
  51.  
  52. break
  53.  
  54. case NSStreamEventHasSpaceAvailable: 
  55.  
  56. event = @”NSStreamEventHasSpaceAvailable”; 
  57.  
  58. if (flag ==0 && theStream == _outputStream) { 
  59.  
  60. //輸出 
  61.  
  62. UInt8 buff[] = ”Hello Server!”; ④ 
  63.  
  64. [_outputStream write:buff maxLength: strlen((const char*)buff)+1]; ⑤ 
  65.  
  66. //關閉輸出流 
  67.  
  68. [_outputStream close]; 
  69.  
  70.  
  71. break
  72.  
  73. case NSStreamEventErrorOccurred: 
  74.  
  75. event = @”NSStreamEventErrorOccurred”; 
  76.  
  77. [self close]; ⑥ 
  78.  
  79. break
  80.  
  81. case NSStreamEventEndEncountered: 
  82.  
  83. event = @”NSStreamEventEndEncountered”; 
  84.  
  85. NSLog(@”Error:%d:%@”,[[theStream streamError] code], 
  86.  
  87. [[theStream streamError] localizedDescription]); 
  88.  
  89. break
  90.  
  91. default
  92.  
  93. [self close];  ⑦ 
  94.  
  95. event = @”Unknown”; 
  96.  
  97. break
  98.  
  99.  
  100. NSLog(@”event——%@”,event); 
  101.  

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

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

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

 

  1. -(void)close 
  2.  
  3.  
  4. [_outputStream close]; 
  5.  
  6. [_outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] 
  7.  
  8. forMode:NSDefaultRunLoopMode]; 
  9.  
  10. [_outputStream setDelegate:nil]; 
  11.  
  12. [_inputStream close]; 
  13.  
  14. [_inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] 
  15.  
  16. forMode:NSDefaultRunLoopMode]; 
  17.  
  18. [_inputStream setDelegate:nil]; 
  19.  
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

调兵山市| 金坛市| 增城市| 章丘市| 丹巴县| 前郭尔| 宜兰市| 安多县| 镇康县| 靖州| 石门县| 吴桥县| 合江县| 临夏县| 饶河县| 景洪市| 堆龙德庆县| 尚义县| 高淳县| 津市市| 咸丰县| 来凤县| 湖州市| 太和县| 清苑县| 赤城县| 小金县| 蕲春县| 万安县| 尚志市| 鹤庆县| 武义县| 荔波县| 乌海市| 宣恩县| 志丹县| 闸北区| 三门峡市| 延安市| 凤台县| 南雄市|