#import <UIKit/UIKit.h> // 包含了tcp的socket(GCD/Blocks版本) #import "GCDAsyncSocket.h" // 這是一個接收 消息界面 @interface ViewController : UIViewController <GCDAsyncSocketDelegate> { // 申明一個變量名 TCP socket鏈接 GCDAsyncSocket *serverSocket; // 用來存放全部的socket鏈接 NSMutableArray *allClientArray; } @end
#import "ViewController.h" #import "SendViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.navigationItem.title = @"接收消息"; [self showNavItem]; [self createTcpSocket]; } - (void) createTcpSocket { allClientArray = [NSMutableArray array]; // 建立一個後臺的隊列 等待接收數據 dispatch_queue_t dQueue = dispatch_queue_create("My socket queue", NULL); // 1. 建立一個tcp socket套接字對象 serverSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dQueue socketQueue:nil]; // 2. 綁定監聽端口 [serverSocket acceptOnPort:12345 error:nil]; } #pragma mark - 代理方法 接收到一個請求 - (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket { NSString *ip = [newSocket connectedHost]; uint16_t port = [newSocket connectedPort]; // 這個代理函數被調用的時候就是表示 有人鏈接我了 // newSocket就是新的socket NSLog(@"new socket [%@:%d] is %@", ip, port, newSocket); [allClientArray addObject:newSocket]; // 一直死等讀取newSocket的消息 [newSocket readDataWithTimeout:-1 tag:200]; // 寫一些echo信息 NSString *s = @"Welcome"; NSData *data = [s dataUsingEncoding:NSUTF8StringEncoding]; [newSocket writeData:data withTimeout:60 tag:300]; } #pragma mark - 接收到數據代理函數 - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { NSString *ip = [sock connectedHost]; uint16_t port = [sock connectedPort]; NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"接收到tcp [%@:%d] %@", ip, port, s); NSString *s2 = [NSString stringWithFormat:@"你發的數據是:%@", s]; NSData *databack = [s2 dataUsingEncoding:NSUTF8StringEncoding]; [sock writeData:databack withTimeout:60 tag:400]; // 再次接收數據 由於這個方法只接收一次 [sock readDataWithTimeout:-1 tag:200]; } - (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err { NSLog(@"失去鏈接 %@", err); [allClientArray removeObject:sock]; } - (void) showNavItem { UIBarButtonItem *sendMyself = [[UIBarButtonItem alloc] initWithTitle:@"發送本身" style:UIBarButtonItemStylePlain target:self action:@selector(sendMyself)]; self.navigationItem.rightBarButtonItem = sendMyself; } - (void) sendMyself { SendViewController *svc = [[SendViewController alloc] init]; [self.navigationController pushViewController:svc animated:YES]; }
#import <UIKit/UIKit.h> #import "GCDAsyncSocket.h" @interface SendViewController : UIViewController <GCDAsyncSocketDelegate> { // 這個socket用來作發送使用 固然也能夠接收 GCDAsyncSocket *sendTcpSocket; } @end
#import "SendViewController.h" #import "MBProgressHUD.h" @interface SendViewController () @end @implementation SendViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. self.navigationItem.title = @"發送"; [self showNavItem]; [self createClientTcpSocket]; } - (void) showNavItem { UIBarButtonItem *sendMsg = [[UIBarButtonItem alloc] initWithTitle:@"發送消息" style:UIBarButtonItemStylePlain target:self action:@selector(sendMsg)]; self.navigationItem.rightBarButtonItem = sendMsg; } - (void) createClientTcpSocket { dispatch_queue_t dQueue = dispatch_queue_create("client tdp socket", NULL); // 1. 建立一個 udp socket用來和服務端進行通信 sendTcpSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dQueue socketQueue:nil]; // 2. 鏈接服務器端. 只有鏈接成功後才能相互通信 若是60s鏈接不上就出錯 NSString *host = @"10.0.161.119"; uint16_t port = 12345; [sendTcpSocket connectToHost:host onPort:port withTimeout:60 error:nil]; // 鏈接必須服務器在線 } #pragma mark - 代理方法表示鏈接成功/失敗 回調函數 - (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port { NSLog(@"鏈接成功"); // 等待數據來啊 [sock readDataWithTimeout:-1 tag:200]; } // 若是對象關閉了 這裏也會調用 - (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err { NSLog(@"鏈接失敗 %@", err); // 斷線重連 NSString *host = @"10.0.161.119"; uint16_t port = 12345; [sendTcpSocket connectToHost:host onPort:port withTimeout:60 error:nil]; } #pragma mark - 消息發送成功 代理函數 - (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag { [MBProgressHUD hideHUDForView:self.view animated:YES]; NSLog(@"消息發送成功"); } - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { NSString *ip = [sock connectedHost]; uint16_t port = [sock connectedPort]; NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"接收到服務器返回的數據 tcp [%@:%d] %@", ip, port, s); } - (void) sendMsg { // 寫這裏代碼 NSString *s = @"hello from yang"; NSData *data = [s dataUsingEncoding:NSUTF8StringEncoding]; // 開始發送 [MBProgressHUD showHUDAddedTo:self.view animated:YES]; // 發送消息 這裏不須要知道對象的ip地址和端口 [sendTcpSocket writeData:data withTimeout:60 tag:100]; } - (void)dealloc { NSLog(@"dealloc"); // 關閉套接字 [sendTcpSocket disconnect]; sendTcpSocket = nil; } @end