iOS-UDP无线局域网通讯的简单使用

1.UDP简介

UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是面向非连接的协议,UDP传送数据不需要和服务器连接,只需要知道ip和监听端口,不需要链接没有目的的socket,只是将数据报投递出去,不管接收方是否成功接收到,因此是一种不可靠的传输。但是UDP的开销更小数据传输速率更高,因为不必进行收发数据的确认,所以UDP的实时性更好。

2.UDP特点

1.无连接,发送数据之前不需要建立连接。开销和发送之前的时间延迟较短。 2.尽最大努力交付。(可以采取一定策略实现可靠传输) 3.面向报文,UDP对应用程序交付的报文,添加UDP首部后直接交给IP层。不合并,不拆分。 4.没有拥塞控制,网络拥塞不会使源主机发送率降低。 5.UDP支持一对一,一对多,多对一的交互通信 6.UDP首部开销较小,8字节(TCP为20字节、IP为20字节)

3.UDP开发可使用的类库

1.AsyncUdpSocket
2.GCDAsyncUdpSocket

4.AsyncUdpSocket开发使用说明

在项目中,所用到的类库是AsyncUdpSocket,所以这里基于AsyncUdpSocket对UDP开发做一个简单的文档说明:
1.将AsyncUdpSocket.h, AsyncUdpSocket.m文件拷贝到项目中。在项目target -> build phases -> compile sources -> AsyncUdpSocket文件后面加入 -fobjc-arc ,这是为了使编译器编译的时候将此文件在arc的条件下编译。
2.添加CFNetwork.framework

5.代码示例

@property (nonatomic, strong) AsyncUdpSocket *reciveSocket;//负责接受收数据
@property (nonatomic, strong) AsyncUdpSocket *sendSocket;//负责发送数据
@property (nonatomic, strong) NSString *socketHost;//指定Ip地址发送,这里取的是第一个发送心跳包过来的Ip
@property (nonatomic, strong) NSTimer *heartBeatTimer;//心跳定时器

初始化socket,设置代理,绑定端口号

//收
self.reciveSocket = [[AsyncUdpSocket alloc] initIPv4];
[self.reciveSocket setDelegate:self];
[self.reciveSocket bindToPort:1917 error:nil];
[self.reciveSocket receiveWithTimeout:-1 tag:0];
//发
self.sendSocket = [[AsyncUdpSocket alloc] initIPv4];
[self.sendSocket setDelegate:self];
[self.sendSocket connectToHost:self.socketHost onPort:1918 error:nil];
[self.sendSocket enableBroadcast:YES error:nil];
//开启定时器
self.heartBeatTimer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(heartBeatToSocket) userInfo:nil repeats:YES];
[self.heartBeatTimer fire];

心跳包就是广播255.255.255.255,确保在同一局域网的都能收到心跳

NSString *heartBeat = @"heartBeat";
NSData *sendData = [heartBeat dataUsingEncoding:NSUTF8StringEncoding];
if ([self.sendSocket sendData:sendData toHost:@"255.255.255.255" port:1917 withTimeout:-1 tag:1]) {
    NSLog(@"发送指令成功");
}else {
    NSLog(@"发送指令失败"); 
}
[self.sendSocket receiveWithTimeout:-1 tag:1]; 
[self.reciveSocket receiveWithTimeout:-1 tag:0];

AsyncUDPSocketDelegate的代理方法

- (void)onUdpSocket:(AsyncUdpSocket *)sock didSendDataWithTag:(long)tag
{
    //!<信息发送成功
}
- (BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long)tag fromHost:(NSString *)host port:(UInt16)port
{
    //过滤来自本机的消息 继续监听接收消息
    NSString *IPAdress = host;
    if ([IPAdress isEqualToString:[IPHelper deviceIPAdress]]) {
        [self.reciveSocket receiveWithTimeout:-1 tag:0];
        return YES;
    }
    self.socketHost = host;
    //!<接收到了信息  在这里解包
    NSString *reciveStr  =[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    if ([reciveStr isEqualToString:@"heartBeat"]) {
        [self heartBeatToSocket];//收到心跳包后回应一个心跳
    }else {
        if (self.block) {
            self.block(reciveStr);
        }
    }
    return YES;
}
- (void)onUdpSocket:(AsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError *)error
{
    NSLog(@"发送失败:%@",error);
}
-(void)onUdpSocket:(AsyncUdpSocket *)sock didNotReceiveDataWithTag:(long)tag dueToError:(NSError *)error
{
    NSLog(@"接受失败:%@",error);
}

6.Demo

传送门

你可能感兴趣的:(iOS-UDP无线局域网通讯的简单使用)