iOS长连接Socket使用--AsyncSocket
2016-07-21 17:13
519 查看
SOCKET:TCP/IP网络的API。Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。Socket的出现只是使得程序员更方便地使用TCP/IP协议栈而已,是对TCP/IP协议的抽象,从而形成了我们知道的一些最基本的函数接口。
一般有不定时的向服务器传送数据的需求时,使用长连接, iOS开发中长连接的使用一般使用第三方库AsyncSocket, 对socket的封装比较好,使用起来很方便.
下载AsyncSocket https://github.com/robbiehanson/CocoaAsyncSocket
将RunLoop文件夹下的AsyncSocket.h, AsyncSocket.m, AsyncUdpSocket.h, AsyncUdpSocket.m 文件拷贝到自己的project中
添加 依赖库 CFNetwork.framework
1. 先创建一个单例类,命名SocketTool
SocketTool.h
SocketTool.m
2. 在SocketTool.h中导入
声明变量
声明连接和断开的方法
代理
枚举
在SocketTool.m实现方法
在SocketTool.m成功 和 失败的回调方法
得到服务器下发消息会调用的方法
心跳连接方法
至此连接类已经完成
使用
导入#import "SocketTool.h"
一般有不定时的向服务器传送数据的需求时,使用长连接, iOS开发中长连接的使用一般使用第三方库AsyncSocket, 对socket的封装比较好,使用起来很方便.
下载AsyncSocket https://github.com/robbiehanson/CocoaAsyncSocket
将RunLoop文件夹下的AsyncSocket.h, AsyncSocket.m, AsyncUdpSocket.h, AsyncUdpSocket.m 文件拷贝到自己的project中
添加 依赖库 CFNetwork.framework
1. 先创建一个单例类,命名SocketTool
SocketTool.h
// // SocketTool.h // SocketTest #import <Foundation/Foundation.h> @interface SocketTool : NSObject + (SocketTool *)shareInstance; @end
SocketTool.m
#import "SocketTool.h" @implementation SocketTool + (SocketTool *)shareInstance { static SocketTool *sharedInstance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedInstance = [[self alloc] init]; }); return sharedInstance; } @end
2. 在SocketTool.h中导入
#import <sys/socket.h> #import <netinet/in.h> #import <arpa/inet.h> #import <unistd.h> #import "AsyncSocket.h"
声明变量
@property (nonatomic, strong) AsyncSocket *socket; @property (nonatomic, copy) NSString *socketHost; @property (nonatomic, assign) UInt16 socketPort; //端口号 @property (nonatomic, strong) NSTimer *connectTimer; // 计时器
声明连接和断开的方法
- (void)socketConnectHost; // socket连接 // 声明断开连接方法 - (void)cutOffSocket; // 断开socket连接.
代理
@interface SocketTool : NSObject<AsyncSocketDelegate>
枚举
enum { SocketOfflineByServer, // 服务器掉线, 默认为0. SocketOfflineByUser, //用户主动cut. };
在SocketTool.m实现方法
//连接. - (void)socketConnectHost { self.socket = [[AsyncSocket alloc] initWithDelegate:self]; NSError *error = nil; [self.socket connectToHost:self.socketHost onPort:self.socketPort withTimeout:30 error:&error]; } //切断socket - (void)cutOffSocket { self.socket.userData = SocketOfflineByUser; // 声明是由用户主动切断. [self.connectTimer invalidate]; self.connectTimer = nil; [self.socket disconnect]; }
在SocketTool.m成功 和 失败的回调方法
#pragma mark ----------------------- 连接成功回调 -------------------------- - (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port { NSLog(@"连接成功"); // 每隔30秒向服务器发送心跳包 一般设置30秒发送一次心跳包 self.connectTimer = [NSTimer scheduledTimerWithTimeInterval:30 target:self selector:@selector(longConnectToSocket) userInfo:nil repeats:YES]; [self.connectTimer fire]; } //--------------------------------- will连接失败回调 ------------------------------- - (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err { NSLog(@"连接失败"); } //--------------------------------- 连接失败回调 ------------------------------- // 重连 - (void)onSocketDidDisconnect:(AsyncSocket *)sock { NSLog(@"sorry the connect is failure %ld", sock.userData); if (sock.userData == SocketOfflineByServer) { //服务器掉线, 重连 NSLog(@"服务器掉线**********请重新连接"); [self socketConnectHost]; } else if (sock.userData == SocketOfflineByUser) { // 如果用户断开, 不进行重连. return; } }
得到服务器下发消息会调用的方法
// 如果得到数据, 就会调用回调方法. - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { NSLog(@"长连接下发的消息*****************%@",data); // 对得到的data值进行解析与转换即可. }
心跳连接方法
// 心跳连接 - (void)longConnectToSocket { // 根据服务器要求发送固定格式的数据, 假设为指令@"longConnect", 但是一般不会是这么简单地指令. NSLog(@"我发送了一次心跳包"); NSString *longConnect = @"longConnect"; NSData *dataStream = [longConnect dataUsingEncoding:NSUTF8StringEncoding]; [self.socket writeData:dataStream withTimeout:1 tag:1]; }
至此连接类已经完成
使用
导入#import "SocketTool.h"
[SocketTool shareInstance].socketHost = @"<code class="hljs actionscript"><span class="hljs-string"><span class="hljs-string">192.186.100.21</span></span></code>";// host设定 [SocketTool shareInstance].socketPort = 8282;// port设定 // 在连接前先进行手动断开 [SocketTool shareInstance].socket.userData = SocketOfflineByUser; [[SocketTool shareInstance] cutOffSocket]; // 确保断开后再连,如果对一个正处于连接状态的socket进行连接,会出现崩溃 [SocketTool shareInstance].socket.userData = SocketOfflineByServer; [[SocketTool shareInstance] socketConnectHost];
相关文章推荐
- java-模拟tomcat服务器
- Linux socket 初步
- PHP数据库长连接mysql_pconnect的细节
- java socket 注意的地方
- java socket 注意的地方
- C#基于socket模拟http请求的方法
- 简单的Ruby中的Socket编程教程
- Socket不能选择本地IP连接问题如何解决
- C#之Socket操作类实例解析
- 使用C#来编写一个异步的Socket服务器
- C#使用Socket快速判断数据库连接是否正常的方法
- 科学知识:理解socket
- websocket++简单使用及实例分析
- Android聊天工具基于socket实现
- PHP socket 模拟POST 请求实例代码
- php与flash as3 socket通信传送文件实现代码
- 解决time_wait强制关闭socket
- asp.net使用Socket.Send发送信息及Socket.SendFile传输文件的方法
- C#使用Socket上传并保存图片的方法
- 深入php socket的讲解与实例分析