#import//包含了udp的socket(GCD/Blocks版本)#import "GCDAsyncUdpSocket.h"//这是一个接收 消息界面@interface ViewController : UIViewController { //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#import "GCDAsyncUdpSocket.h"@interface SendViewController : UIViewController { //这个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