#import <UIKit/UIKit.h> //包含了udp的socket(GCD/Blocks版本) #import "GCDAsyncUdpSocket.h" //這是一個接收 消息界面 @interface ViewController : UIViewController<GCDAsyncUdpSocketDelegate>{ //udp對象 GCDAsyncUdpSocket *udpServerSoket; } @end
#import "ViewController.h" #import "SendViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.title = @"接收消息"; [self showNavItem]; [self createUdpSocket]; } -(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]; } -(void) createUdpSocket{ //建立一個後臺隊列 等待接收數據 dispatch_queue_t dQueue = dispatch_queue_create("My socket queue", NULL); //第一個參數是該隊列的名字 //1.實例化一個udp socket套接字對象 // udpServerSocket須要用來接收數據 udpServerSoket = [[GCDAsyncUdpSocket alloc]initWithDelegate:self delegateQueue:dQueue socketQueue:nil]; //2.服務器端來監聽端口12345(等待端口12345的數據) [udpServerSoket bindToPort:12345 error:nil]; //3.接收一次消息(啓動一個等待接收,且只接收一次) [udpServerSoket receiveOnce:nil]; } #pragma mark -GCDAsyncUdpSocketDelegate -(void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data fromAddress:(NSData *)address withFilterContext:(id)filterContex { //取得發送發的ip和端口 NSString *ip = [GCDAsyncUdpSocket hostFromAddress:address]; uint16_t port = [GCDAsyncUdpSocket portFromAddress:address]; //data就是接收的數據 NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"[%@:%u]%@",ip, port,s); [self sendBackToHost: ip port:port withMessage:s]; //再次啓動一個等待 [udpServerSoket receiveOnce:nil]; } -(void)sendBackToHost:(NSString *)ip port:(uint16_t)port withMessage:(NSString *)s{ NSString *msg = @"我已接收到消息"; NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding]; [udpServerSoket sendData:data toHost:ip port:port withTimeout:60 tag:200]; } @end
#import <UIKit/UIKit.h> #import "GCDAsyncUdpSocket.h" @interface SendViewController : UIViewController<GCDAsyncUdpSocketDelegate>{ //這個socket用來作發送使用 固然也能夠接收 GCDAsyncUdpSocket *sendUdpSocket; } @end
#import "SendViewController.h" @implementation SendViewController -(void)viewDidLoad{ [super viewDidLoad]; self.navigationItem.title = @"發送"; self.view.backgroundColor = [UIColor whiteColor]; [self showNavItem]; [self createClientUdpSocket]; } - (void) showNavItem { UIBarButtonItem *sendMsg = [[UIBarButtonItem alloc] initWithTitle:@"發送消息" style:UIBarButtonItemStylePlain target:self action:@selector(sendMsg)]; self.navigationItem.rightBarButtonItem = sendMsg; } -(void)createClientUdpSocket{ dispatch_queue_t dQueue = dispatch_queue_create("client udp socket", NULL); //1.建立一個 udp socket用來和服務器端進行通信 sendUdpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dQueue socketQueue:nil]; //2.banding一個端口(可選),若是不綁定端口, 那麼就會隨機產生一個隨機的電腦惟一的端口 //端口數字範圍(1024,2^16-1) [sendUdpSocket bindToPort:8085 error:nil]; //3.等待接收對方的消息 [sendUdpSocket receiveOnce:nil]; } - (void) sendMsg { NSString *s = @"hello IOS"; NSData *data = [s dataUsingEncoding:NSUTF8StringEncoding]; NSString *host = @"10.0.161.87"; uint16_t port = 12345; //開始發送 //改函數只是啓動一次發送 它自己不進行數據的發送, 而是讓後臺的線程慢慢的發送 也就是說這個函數調用完成後,數據並無馬上發送,異步發送 [sendUdpSocket sendData:data toHost:host port:port withTimeout:60 tag:100]; } #pragma mark -GCDAsyncUdpSocketDelegate -(void)udpSocket:(GCDAsyncUdpSocket *)sock didSendDataWithTag:(long)tag{ if (tag == 100) { //NSLog(@"表示標記爲100的數據發送完成了"); } } -(void)udpSocket:(GCDAsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError *)error{ NSLog(@"標記爲tag %ld的發送失敗 失敗緣由 %@",tag, error); } -(void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data fromAddress:(NSData *)address withFilterContext:(id)filterContext{ NSString *ip = [GCDAsyncUdpSocket hostFromAddress:address]; uint16_t port = [GCDAsyncUdpSocket portFromAddress:address]; NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; // 繼續來等待接收下一次消息 NSLog(@"收到服務端的響應 [%@:%d] %@", ip, port, s); [sock receiveOnce:nil]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self sendBackToHost:ip port:port withMessage:s]; }); } -(void)sendBackToHost:(NSString *)ip port:(uint16_t)port withMessage:(NSString *)s{ NSString *msg = @"我再發送消息"; NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding]; [sendUdpSocket sendData:data toHost:ip port:port withTimeout:60 tag:200]; } -(void)dealloc{ NSLog(@"%s",__func__ ); [sendUdpSocket close]; sendUdpSocket = nil; } @end