您的位置:首页 > 移动开发 > IOS开发

IOS UDP通讯

2016-05-03 11:19 489 查看
1.我们利用开源框架AsyncSocket 里面有对UDP, TCP的封装, 一个是GCD(主要是利用Blocks,较为流行), 一个是RunLoop(利用代理模式,使用会越来越少).2.下面仅介绍使用UDP来进行通讯, ViewController 和 SendViewController相互通讯3.首先用SendViewController给ViewController发送消息, ViewController收到后回复SendViewController, SendViewController接收到消息后再回复ViewControll.

#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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: