CocoaAsyncSocket

韩自怡
2023-12-01
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



 类似资料:

相关阅读

相关文章

相关问答