iOS学习笔记4-GCDAsyncUdpSocket的使用(实现异步发送接收数据)

做项目的时候用到了GCDAsyncUdpSocket,所以在此总结下它的用法,作为笔记;

GCDAsyncUdpSocket简介

GCDAsyncUdpSocket开源类库是以苹果的GCD多任务处理机制完成的一个异步交互套接字通讯。如果需要使用同步的,则去寻找AsyncUdpSocket就可以了。该开源库完成了UDP之间的通信,使得UDP通信的编程变得更加简单;

使用方法:

1.源码下载以及导入:

源码在谷歌上一搜便有,下面给出github的地址:https://github.com/robbiehanson/CocoaAsyncSocket
下载即可。
该开源库里面也有相应地示例代码,但如果需要用到我们的代码里面,只需要复制出GCDAsyncUdpSocket.h,GCDAsyncUdpSocket.m文件到工程中就可以了。

2.定义一个GCDAsyncUdpSocket对象

首先,需要导入头文件,在需要引用GCDAsyncUdpSocket的地方(如我定义一个网络类UdpAssociation.m)的.h文件中导入GCDAsyncUdpSocket.h文件
如:

#import "GCDAsyncUdpSocket.h"

接着,在UdpAssociation的头文件里改成:

@interface UdpAssociation : NSObject <GCDAsyncUdpSocketDelegate>

代表着类UdpAssociation要遵守这个协议;
接着,在类UdpAssociation中定义一个GCDAsyncUdpSocket对象
如:

    GCDAsyncUdpSocket *udpSocket;

3.初始化

在初始化函数中需要完成几个步骤:
·实例化一个GCDAsyncUdpSocket对象
如:

udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];

解释:
查看它的源代码,会发现还有好几种初始化的方法,这里选用的是其中的一种,initWithDelegate:self设置代理是自己,意味着自己会接受到与该协议相关的任何消息,delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);这里给delegateQueue加的是全局并发的队列,也可以给其它的队列;
·接着绑定通信端口

        NSError *error = nil;
        if(![udpSocket bindToPort :servicePort error:&error])
        {
            NSLog(@"error in bindToPort");
            //return;
        }

·到此所有初始化工作已经完成。

4.写代理函数

该开源库总共需要写6个代理函数:
可以查看协议头文件可得:

@protocol GCDAsyncUdpSocketDelegate
@optional

/**
 * By design, UDP is a connectionless protocol, and connecting is not needed.
 * However, you may optionally choose to connect to a particular host for reasons
 * outlined in the documentation for the various connect methods listed above.
 * 
 * This method is called if one of the connect methods are invoked, and the connection is successful.
**/
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didConnectToAddress:(NSData *)address;

/**
 * By design, UDP is a connectionless protocol, and connecting is not needed.
 * However, you may optionally choose to connect to a particular host for reasons
 * outlined in the documentation for the various connect methods listed above.
 * 
 * This method is called if one of the connect methods are invoked, and the connection fails.
 * This may happen, for example, if a domain name is given for the host and the domain name is unable to be resolved.
**/
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didNotConnect:(NSError *)error;

/**
 * Called when the datagram with the given tag has been sent.
**/
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didSendDataWithTag:(long)tag;

/**
 * Called if an error occurs while trying to send a datagram.
 * This could be due to a timeout, or something more serious such as the data being too large to fit in a sigle packet.
**/
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError *)error;

/**
 * Called when the socket has received the requested datagram.
**/
  (void)udpSocket:(GCDAsyncUdpSocket *)sock 
   didReceiveData:(NSData *)data 
      fromAddress:(NSData *)address
withFilterContext:(id)filterContext;

/**
 * Called when the socket is closed.
**/
- (void)udpSocketDidClose:(GCDAsyncUdpSocket *)sock withError:(NSError *)error;

@end

其中最重要的是写好接收的回调函数就可以了:

   (void)udpSocket:(GCDAsyncUdpSocket *)sock 
    didReceiveData:(NSData *)data 
       fromAddress:(NSData *)address
 withFilterContext:(id)filterContext;

data就是接收到得数据,在该函数写好具体的处理函数就好了。

5.开始发送或者接受:

·首先谈谈接收:
在初始化的最后加上下面接收这句,便开始接收了(一旦有数据发送过来)
首先接收是异步的,所以对于大量数据同时发送的时候要注意接收的顺序问题;
接着,该开源库接收也有两种方法:

[udpSocket receiveOnce:&error];
[udpSocket beginReceiving:&error];

两种的区别是:[udpSocket receiveOnce:&error]只能接收一次数据,而在正常的UDP通信中是可不停地接收的,如果需要不停地接收那就适合使用第二条[udpSocket beginReceiving:&error];
但两者又有关联,两者是可以互相转化的,比如,在某种情况下,你需要只接受一次数据,那就可以先选用[udpSocket receiveOnce:&error];接下来在完成某件事情后,你需要开始正常的不停的接收了,这时候只需要再写一句:[udpSocket beginReceiving:&error];这样就能够转化了。
·发送
发送比较简答,只需要在需要发送数据的地方加上:

[udpSocket sendData:sendData toHost:serviceAddress port:servicePort withTimeout:-1 tag:tag];

看源码也会发现还有许多中发送的方法,具体可以去源码查看;
注意:这里的发送也是异步的。
withTimeout设置成-1代表超时时间为-1,即永不超时;
同时这里的tag也可以作为一个标签使用,具体用法可以参考以下博文:
《GCDAsyncSocket类库,IOS下TCP通讯使用心得》

好了,到此,你应该能够利用该开源库进行基本的通信了!

你可能感兴趣的:(学习笔记)