標籤:
以前實現簡單 Server 程式,服務端通過 void WriteStreamClientCallBack(CFWriteStreamRef stream, CFStreamEventType eventType, void* clientCallBackInfo) 函數向client發送“你好。client!”的訊息,假設client接收成功的話就會顯示“你好。client!
”。須要顯示服務端發送過來的訊息。那麼就須要定義一個UILabel輸出口(IBOutlet)來顯示訊息;client還須要加入兩個button,一個用來接收服務端訊息的動作事件方法 receiveData:和發送client“收到啦,服務端”訊息的動作事件方法 sendData:;加入關聯就能夠了,比較簡單,以下來看一下詳細實現的代碼:
ViewController.h
#import <UIKit/UIKit.h>#import <CoreFoundation/CoreFoundation.h>#include <sys/socket.h>#include <netinet/in.h>#define PORT 8734 //將連接埠設定為8734。能夠依據詳細情況改變@interface ViewController : UIViewController<NSStreamDelegate>{ int flag ; //操作標誌 0為發送 1為接收}@property (nonatomic, retain) NSInputStream *inputStream;@property (nonatomic, retain) NSOutputStream *outputStream;@property (weak, nonatomic) IBOutlet UILabel *message; //在client顯示來自服務端的訊息- (IBAction)sendData:(id)sender; //發送client的訊息- (IBAction)receiveData:(id)sender; //接收來自服務端的訊息@end ViewController.m
#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad{ [super viewDidLoad]; }- (void)didReceiveMemoryWarning{ [super didReceiveMemoryWarning];}//初始化client網路連接- (void)initNetworkCommunication{ CFReadStreamRef readStream; CFWriteStreamRef writeStream; //這裡須要填寫 IP 位址,依據自己路由能夠用的 IP來定,這裡是192.168.1.103,假設不知道能夠下載 IP 掃描器 CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"192.168.1.103", PORT, &readStream, &writeStream); self.inputStream = (__bridge_transfer NSInputStream *)readStream; //將CFStream對象轉化為NSStream對象 self.outputStream = (__bridge_transfer NSOutputStream *)writeStream; //將CFStream對象轉化為NSStream對象 [self.inputStream setDelegate:self]; [self.outputStream setDelegate:self]; [self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; //NSStream 方法 scheduleInRunLoop: 設定 Run Loop [self.outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [self.inputStream open]; //NSStream 的 open 方法來開啟資料流對象 [self.outputStream open]; }//關閉資料流操作-(void)close{ [self.outputStream close]; [self.outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [self.outputStream setDelegate:nil]; [self.inputStream close]; [self.inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [self.inputStream setDelegate:nil];}//從client發送資料事件方法- (IBAction)sendData:(id)sender { flag = 0; //表示發送 [self initNetworkCommunication]; }//從服務端接收資料事件方法- (IBAction)receiveData:(id)sender { flag = 1; //表示接收 [self initNetworkCommunication]; }-(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[2048]; //讀取資料準備緩衝區,本例中設定的是2048位元組,這個大小會對流的讀取有非常大影響 int len; while([self.inputStream hasBytesAvailable]) { len = [self.inputStream read:buffer maxLength:sizeof(buffer)]; //讀取資料到緩衝區 if (len > 0) { [input appendBytes:buffer length:len]; } } NSString *resultstring = [[NSString alloc] initWithData:input encoding:NSUTF8StringEncoding]; NSLog(@"接收:%@",resultstring); self.message.text = resultstring; } break; case NSStreamEventHasSpaceAvailable: //這個流能夠接收資料的寫入,在寫資料時使用 event = @"NSStreamEventHasSpaceAvailable"; if (flag ==0 && theStream == _outputStream) { //輸出 UInt8 buff[] = "收到啦,服務端。"; //向服務端發送的訊息 [self.outputStream write:buff maxLength: strlen((const char*)buff)+1]; //向服務端寫入資料方法 //必須關閉輸出資料流否則,server端一直讀取不會停止。 [self.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; }}@end
從代碼能夠知道。client採用的是 APPLE 自家的 NSStream 來實現的,都是比較簡單的基本資料流操作。
如有哪些不正確的地方,歡迎指出!
著作權聲明:本文博主原創文章,部落格,未經同意不得轉載。
iOS 基於Socket 的 C/S 網路通訊結構(下一個)