Socket 这个概念我就不多说了 不懂得请自行百度
接下来进入正题 如何封装socket
基于AsyncSocket 下载地址为 code.google.com/p/cocoaasyncsocket/ 恩 下面开始讲基于它的简单封装了
首先,调用此API时需先引入CFNetWork.framework
然后在#import "AsyncSocket.h"就可以直接调用了
闲话不多说,上代码:
ZHAsyncSocket.h 文件如下
#import <Foundation/Foundation.h>
#import "AsyncSocket.h"
@interface ZHAsyncSocket : NSObject
@property (nonatomic, strong) AsyncSocket *socket; // socket
@property (nonatomic, strong) AsyncSocket *recvSocket;
//socket地址
@property (nonatomic, copy ) NSString *socketHost; // socket的Host
//socket 端口
@property (nonatomic, assign) UInt16 socketPort; // socket的prot
+ (ZHAsyncSocket *)sharedInstance;
/*
* 设置地址和端口
*/
-(void)setHostAndPort:(NSString *)socketHost withPort:(UInt16)socketPort;
/*
* socket连接
*/
-(void)socketConnectHost;
/*
* 主动关闭切断socket
*/
-(void)cutOffSocket;
/*
* 发送数据
*/
-(void)sendData:(NSString *)str withTag:(long)tag;
/*
* 连接前的自检
*/
-(void)openClient;
@end
ZHAsyncSocket.m 文件如下
enum{
SocketOfflineByServer,//服务器
SocketOfflineByUser,//用户
};
#define k_DCS_HEART_FLAG -10001
@interface ZHAsyncSocket()<AsyncSocketDelegate>
{
}
@property (nonatomic, strong) NSTimer *connectTimer; // 计时器
@end
@implementation ZHAsyncSocket
+(ZHAsyncSocket *) sharedInstance
{
static ZHAsyncSocket *sharedInstace = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstace = [[self alloc] init];
});
return sharedInstace;
}
-(void)setHostAndPort:(NSString *)socketHost withPort:(UInt16)socketPort {
self.socketHost = socketHost;
self.socketPort = socketPort;
}
#pragma mark - socket连接
-(void)socketConnectHost{
self.socket = [[AsyncSocket alloc] initWithDelegate:self];
NSError *error = nil;
[self.socket connectToHost:self.socketHost onPort:self.socketPort withTimeout:20 error:&error];
}
#pragma mark -- 连接前的自检
-(void)openClient{
// 确保断开后再连,如果对一个正处于连接状态的socket进行连接,会出现崩溃
// 在连接前先进行手动断开
self.socket.userData = SocketOfflineByUser;
[self cutOffSocket];
self.socket.userData = SocketOfflineByServer;
[self socketConnectHost];
}
#pragma mark - 主动关闭切断socket
-(void)cutOffSocket{
self.socket.userData = SocketOfflineByUser;
[self.connectTimer invalidate];
[self.socket disconnect];
}
#pragma mark - 连接成功回调
-(void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
NSLog(@"连接成功");
// self.connectTimer = [NSTimer scheduledTimerWithTimeInterval:30 target:self selector:@selector(longConnectToSocket) userInfo:nil repeats:YES];
// [self.connectTimer fire];
[self.socket readDataWithTimeout:-1 tag:1];
NSString *str = @"连接成功";
NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];
[self.socket writeData:data withTimeout:10 tag:k_DCS_HEART_FLAG];
}
#pragma mark - 心跳连接
-(void)longConnectToSocket{
NSLog(@"心跳检测");
// 根据服务器要求发送心跳
//NSData *dataStream = [longConnect dataUsingEncoding:NSUTF8StringEncoding];
NSString *str = @"心跳检测";
NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];
// [self.socket writeData:data withTimeout:10 tag:k_DCS_HEART_FLAG];
}
#pragma mark - 断线处理
-(void)onSocketDidDisconnect:(AsyncSocket *)sock
{
//NSLog(@"sorry the connect is failure %ld",sock.userData);
if (sock.userData == SocketOfflineByServer) {
// 服务器掉线,重连
[self socketConnectHost];
}
else if (sock.userData == SocketOfflineByUser) {
// 如果由用户断开,不进行重连
return;
}
}
#pragma mark - 接收数据
-(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
// 对得到的data值进行解析与转换即可
NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"我接收到了数据%@",result);
[self.socket readDataWithTimeout:-1 tag:tag];
}
#pragma mark - 发送数据
-(void)sendData:(NSString *)str withTag:(long)tag {
NSLog(@"发送数据");
NSString *Str = @"发送数据";
NSData* data = [Str dataUsingEncoding:NSUTF8StringEncoding];
[self.socket writeData:data withTimeout:-1 tag:tag];
}
#pragma mark - 已经发送完成数据
-(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag
{
NSLog(@"我已经完成数据");
}
-(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket
{
//接受数据,死循环
[newSocket readDataWithTimeout:-1 tag:100];
NSLog(@"接受数据,死循环");
}
@end
调用更简单 方法如下
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//建立长连接
[self setupConnection];
}
-(void)setupConnection {
self.asyncSocket = [ZHAsyncSocket sharedInstance];
//设置地址和端口
[self.asyncSocket setHostAndPort:XYS_LONG_CONNECTION_HOST withPort:[XYS_LONG_CONNECTION_PORT intValue]];
[self.asyncSocket openClient];
}
PS: XYS_LONG_CONNECTION_HOST 你的地址
XYS_LONG_CONNECTION_PORT 你的端口