CocoaAsyncSocket 详细介绍
CocoaAsyncSocket支持tcp和udp。
其中:
-
AsyncSocket类是支持TCP的
-
AsyncUdpSocket是支持UDP的
AsyncSocket是封装了CFSocket和CFSteam的TCP/IP socket网络库。它提供了异步操作,本地cocoa类的基于delegate的完整支持。主要有以下特性:
-
队列的非阻塞的读和写,而且可选超时。你可以调用它读取和写入,它会当完成后告知你
-
自动的socket接收。如果你调用它接收连接,它将为每个连接启动新的实例,当然,也可以立即关闭这些连接
-
委托(delegate)支持。错误、连接、接收、完整的读取、完整的写入、进度以及断开连接,都可以通过委托模式调用
-
基于run loop的,而不是线程的。虽然可以在主线程或者工作线程中使用它,但你不需要这样做。它异步的调用委托方法,使用NSRunLoop。委托方法包括socket的参数,可让你在多个实例中区分
-
自包含在一个类中。你无需操作流或者socket,这个类帮你做了全部
-
支持基于IPV4和IPV6的TCP流
AsyncUdpSocket是UDP/IP socket网络库,包装自CFSocket。它的工作很像TCP版本,只不过是用于处理UDP的。它包括基于非阻塞队列的发送接收操作,完整的委托支持,基于runloop,自包含的类,以及支持IPV4和IPV6。
具体用法:
1.MRC环境
这个框架只有arc的版本。所以引入GCDAsyncSocket的.h和.m文件后,修改xcode中项目的属性。
1)targets中“build settings”中找到Compiler for c/c++/Objective-c的选项。改为Apple LLVM compiler 3.0 只要是3.0或以上就可以
2)在“build phases”中“compile sources”中找到GCDAsyncSocket.m,增加参数-fobj-arc
3)引入GCDAsyncSocket所需要的框架,CFNetwork和security这两个
2.ARC环境
1)手动添加,直接下载源码,直接放到项目中,添加必要的库CFNetwork和security
2)cocoaposd管理 创建Podfile文件,里面添加 pod 'CocoaAsyncSocket','~>7.6.0'
客户端代码实现
- (void) initNetwork{
socket= [[GCDAsyncSocketalloc] initWithDelegate:selfdelegateQueue:dispatch_get_main_queue()];
NSError*error = nil;
if(![socketconnectToHost:@"服务器IP"onPort:服务器端口 error:&error]) {
NSLog(@"is aready connected");
}
}
- (void) sendData{
NSLog(@"send Message to server");
NSData*datas = [@"client send msg"dataUsingEncoding:NSUTF8StringEncoding];
[socket writeData:datas withTimeout:-1 tag:1];//这里tag没用到
[socket readDataWithTimeout:-1 tag:1];//这句必须加,否则收不到服务器返回数据
}
- (void) socket:(GCDAsyncSocket*)sock didConnectToHost:(NSString*)host port:(uint16_t)port{
NSLog(@"connected to the server");
}
- (void) socket:(GCDAsyncSocket*)sock didReadData:(NSData*)data withTag:(long)tag{
NSString*msg = [[NSStringalloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"return message=%@",msg);
}
- (void) socketDidDisconnect:(GCDAsyncSocket*)sock withError:(NSError*)err{
NSLog(@"close connected");
}
服务器端代码:
#import"ViewController.h"
#import"GCDAsyncSocket.h"
@interfaceViewController()
@property(weak,nonatomic)IBOutletUITextField*portF;
@property(weak,nonatomic)IBOutletUITextField*messageTF;
@property(weak,nonatomic)IBOutletUITextView*showContentMessageTV;
//服务器socket(开放端口,监听客户端socket的链接)
@property(nonatomic)GCDAsyncSocket*serverSocket;
//保护客户端socket
@property(nonatomic)GCDAsyncSocket*clientSocket;
@end
@implementationViewController
#pragma mark -服务器socket Delegate
- (void)socket:(GCDAsyncSocket*)sock didAcceptNewSocket:(GCDAsyncSocket*)newSocket{
//保存客户端的socket
self.clientSocket= newSocket;
[selfshowMessageWithStr:@"链接成功"];
[selfshowMessageWithStr:[NSStringstringWithFormat:@"服务器地址:%@ -端口:%d", newSocket.connectedHost, newSocket.connectedPort]];
[self.clientSocketreadDataWithTimeout:-1tag:0];
}
//收到消息
- (void)socket:(GCDAsyncSocket*)sock didReadData:(NSData*)data withTag:(long)tag{
NSString*text = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding];
[selfshowMessageWithStr:text];
[self.clientSocketreadDataWithTimeout:-1tag:0];
}
//发送消息
- (IBAction)sendMessage:(id)sender {
NSData*data = [self.messageTF.textdataUsingEncoding:NSUTF8StringEncoding];
//withTimeout -1:无穷大,一直等
//tag:消息标记
[self.clientSocketwriteData:datawithTimeout:-1tag:0];
}
//开始监听
- (IBAction)startReceive:(id)sender {
//2、开放哪一个端口
NSError*error =nil;
BOOLresult = [self.serverSocketacceptOnPort:self.portF.text.integerValueerror:&error];
if(result && error ==nil) {
//开放成功
[selfshowMessageWithStr:@"开放成功"];
}
}
//接受消息,socket是客户端socket,表示从哪一个客户端读取消息
- (IBAction)ReceiveMessage:(id)sender {
[self.clientSocketreadDataWithTimeout:11tag:0];
}
- (void)showMessageWithStr:(NSString*)str{
self.showContentMessageTV.text= [self.showContentMessageTV.textstringByAppendingFormat:@"%@\n",str];
}
- (void)viewDidLoad {
[superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// 1、初始化服务器socket,在主线程力回调
self.serverSocket= [[GCDAsyncSocketalloc]initWithDelegate:selfdelegateQueue:dispatch_get_main_queue()];
}
- (void)didReceiveMemoryWarning {
[superdidReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end