您的位置:首页 > 移动开发 > IOS开发

iOS 基于AsyncSocket的二次开发

2016-11-15 18:07 399 查看
前言:本文主要基于AsyncSocket的二次开发,接收数据本文主要提供3种方式,其中包括报文中有报文头的情况、普通情况、需要解密的情况。

通过调用实例化方法

/**
实例化HSShareSocket

@param host 主机ip
@param port 端口
@param requestData 发送的数据
@param requestTag 请求标志
@param success 成功回调
@param failure 失败回调
@return 返回HSShareSocket对象
*/
+ (HSShareSocket *)shareSocketWithHost:(NSString *)host port:(UInt16)port requestData:(NSData *)requestData requestTag:(RequestTag)requestTag success:(SocketReadDataSuccessBlock)success failure:(SocketDisconnectFailureBlock)failure;


有需要的话,需要在下面这个方法进行修改

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;


详细代码如下:

.h文件

#import <Foundation/Foundation.h>
@class AsyncSocket;

//请求标志
typedef NS_ENUM(NSInteger,RequestTag) {
requestTag_other = 99,
};

typedef void(^SocketReadDataSuccessBlock)(NSDictionary *dict,RequestTag requestTag);
typedef void(^SocketDisconnectFailureBlock)(NSError *err);

@interface HSShareSocket : NSObject

/** 实例化HSShareSocket @param host 主机ip @param port 端口 @param requestData 发送的数据 @param requestTag 请求标志 @param success 成功回调 @param failure 失败回调 @return 返回HSShareSocket对象 */ + (HSShareSocket *)shareSocketWithHost:(NSString *)host port:(UInt16)port requestData:(NSData *)requestData requestTag:(RequestTag)requestTag success:(SocketReadDataSuccessBlock)success failure:(SocketDisconnectFailureBlock)failure;

+ (HSShareSocket *)shareSocket;

//建立socket连接
- (void)socketConnectHost;

//断开连接
- (void)closeConnect;

//连接主机ip
@property (nonatomic,copy) NSString *socketHostIp;

//连接端口
@property (nonatomic,assign) UInt16 socketPort;

//发送数据
@property (nonatomic,copy) NSData *requestData;

//请求标志
@property (nonatomic,assign) NSInteger requestTag;

//读取数据成功回调
@property (nonatomic,copy) SocketReadDataSuccessBlock socketReadDataSuccessBlock;

//链接失败回调
@property (nonatomic,copy) SocketDisconnectFailureBlock socketDisconnectFailureBlock;

@end


.m文件

#import "HSShareSocket.h"
#import "AsyncSocket.h"

//设置超时时间
static const float kSocketTimeOut = 30;

@interface HSShareSocket ()<AsyncSocketDelegate>

@property (nonatomic,strong) AsyncSocket *asyncSocket;

//接收数据
@property (nonatomic,strong) NSData      *receivedData;

//报文长度
@property (nonatomic,assign) int         messageLength;

@end

@implementation HSShareSocket

#pragma mark 实例化HSShareSocket
+ (HSShareSocket *)shareSocketWithHost:(NSString *)host port:(UInt16)port requestData:(NSData *)requestData requestTag:(RequestTag)requestTag success:(SocketReadDataSuccessBlock)success failure:(SocketDisconnectFailureBlock)failure
{
HSShareSocket *shareSocket = [HSShareSocket shareSocket];
[shareSocket closeConnect];
shareSocket.socketHostIp = host;
shareSocket.socketPort = port;
shareSocket.requestData = requestData;
shareSocket.requestTag = requestTag;
shareSocket.socketReadDataSuccessBlock = success;
shareSocket.socketDisconnectFailureBlock = failure;
[shareSocket socketConnectHost];
return shareSocket;
}

+ (HSShareSocket *)shareSocket
{
static HSShareSocket *shareSocket = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
shareSocket = [[self alloc] init];
});
return shareSocket;
}

#pragma mark 建立socket连接
- (void)socketConnectHost
{
NSError *error = nil;
[self.asyncSocket connectToHost:self.socketHostIp onPort:self.socketPort error:&error];
}

- (AsyncSocket *)asyncSocket
{
if (!_asyncSocket) {
_asyncSocket = [[AsyncSocket alloc] initWithDelegate:self];
[_asyncSocket setRunLoopModes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
}
return _asyncSocket;
}

#pragma mark 断开连接
- (void)closeConnect
{
//1.清空接收数据
self.receivedData = nil;
//2.断开连接
[self.asyncSocket disconnect];
}

#pragma mark 连接成功
- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
//1.发送数据
[self sendData:self.requestData];
//2.读取数据
[self.asyncSocket readDataWithTimeout:kSocketTimeOut tag:self.requestTag];
}

#pragma mark 发送数据
- (void)sendData:(NSData *)data
{
//1.写入
[self.asyncSocket writeData:data withTimeout:kSocketTimeOut tag:self.requestTag];
//2.读取
[self.asyncSocket readDataWithTimeout:kSocketTimeOut tag:self.requestTag];
}

#pragma mark 接收数据处理
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
NSLog(@"接受数据长度:%lu from remote ip %@",(unsigned long)data.length,[sock connectedHost]);
/*注:根据不同的tag进行相应的处理
1.对带有报文长度的做以下处理,可根据相应的来判断
if (_receivedData == nil) {
Byte *byte = (Byte *)[data bytes];
int a1 = (int)byte[0];
int a2 = (int)byte[1];
_messageLength = a1*256 + a2;
NSMutableData *mutableData = [NSMutableData data];
[mutableData appendData:data];
[mutableData replaceBytesInRange:NSMakeRange(0, 2) withBytes:NULL length:0];
data = mutableData;
}else{
if ((_receivedData.length + data.length) > _messageLength) {
//如果接收的报文长度大于报文头长度,则断开连接
[self closeConnect];
}
}
2.如果不需要加密,则调用
[self receiveDataNoEncrypt:data requestTag:tag];
3.需要加密的,则调用
[self receiveData:data requestTag:tag];
*/

//默认为不加密处理
[self receiveDataNoEncrypt:data requestTag:tag];
}

#pragma mark 连接失败
- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
{
if (_socketDisconnectFailureBlock) {
_socketDisconnectFailureBlock(err);
}
}

#pragma mark 根据tag写入数据(当完成写入的时候调用)
- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag
{
}

#pragma mark 当这个socket是连接的时候,这个方法将会返回一个yes继续或者no停止
- (BOOL)onSocketWillConnect:(AsyncSocket *)sock
{
return YES;
}

#pragma mark socket断开连接
- (void)onSocketDidDisconnect:(AsyncSocket *)sock
{
}

#pragma mark 拼接报文(无需解密)
- (void)receiveDataNoEncrypt:(NSData *)data requestTag:(long)tag
{
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
if (dict != nil){
[self receivedSuccess:dict requestTag:tag];
}
else {
if (_receivedData == nil)
_receivedData = data;
else {
NSMutableData *dates = [[NSMutableData alloc]init];
[dates appendData:_receivedData];
[dates appendData:data];
dict = [NSJSONSerialization JSONObjectWithData:dates options:NSJSONReadingMutableLeaves error:nil];
if (dict != nil){
[self receivedSuccess:dict requestTag:tag];
}else{
_receivedData = dates;
[self.asyncSocket readDataWithTimeout:-1 tag:tag];
}
}
}
}

#pragma mark - 报文拼接(需要进行解密)
- (void)receiveData:(NSData *)data dataStr:(NSData *)dataStr str:(NSString *)str requestTag:(long)tag
{
if (str != nil) {
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:dataStr options:NSJSONReadingMutableContainers error:nil];
if (dic != nil) {
[self receivedSuccess:dic requestTag:tag];
}else{
[self receiveData:data requestTag:tag];
}
}else {
[self receiveData:data requestTag:tag];
}
}

#pragma mark 拼接报文(需解密)
- (void)receiveData:(NSData *)data requestTag:(long)tag
{
if (_receivedData == nil)
_receivedData = data;
else {
NSMutableData *dates = [[NSMutableData alloc]init];
[dates appendData:_receivedData];
[dates appendData:data];
NSString *str1 = [[NSString alloc]initWithData:dates encoding:NSUTF8StringEncoding];
str1 = [str1 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if (str1 != nil) {
//进行相关的解密
//            str1 = [str1 aes256_decrypt:_KeyAES];
NSData *dataStr1 = [str1 dataUsingEncoding:NSUTF8StringEncoding];
if (dataStr1 != nil) {
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:dataStr1 options:NSJSONReadingMutableLeaves error:nil];
if (dict != nil){
[self receivedSuccess:dict requestTag:tag];
}
else{
_receivedData = dates;
[self.asyncSocket readDataWithTimeout:kSocketTimeOut tag:tag];
}
}else{
_receivedData = dates;
[self.asyncSocket readDataWithTimeout:kSocketTimeOut tag:tag];
}
}
}
}

#pragma mark 接收到完整数据后,进行回调并关闭连接
- (void)receivedSuccess:(NSDictionary *)dic requestTag:(long)tag
{
//1.回调
if (_socketReadDataSuccessBlock) {
_socketReadDataSuccessBlock(dic,tag);
}

//2.关闭连接
[self closeConnect];
}

@end


文件连接:http://download.csdn.net/detail/u011154007/9683688
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: