AsyncSocket使用心得和一些需要注意的地方

来源:互联网 发布:云计算峰会的会议主题 编辑:程序博客网 时间:2024/05/22 07:42

首先 下载源代码

倒入runloop文件夹下的 四个文件即可

AsyncSocket *socket=[[AsyncSocketalloc]initWithDelegate:self];

 NSError *error;

 [socket  connectToHost:h onPort:p withTimeout:-1error:&error ];

 

 

然后实现一些Delegate方法

 

A:- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port;
B:- (void)onSocketDidSecure:(AsyncSocket *)sock;
C:- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
D:- (void)onSocketDidDisconnect:(AsyncSocket *)sock;
E:- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;

 

监听网络操作

如果链接成功会调用A   

如果我们想读取数据  就在A方法中  加入[socket readDataWithTimeout:-1 tag:0];  当收到数据的时候  会调用E  当调用E之后 我们的这个读取请求就完成了

不再监听网络, 若想一直监听网络  在E中 也加入[socket readDataWithTimeout:-1 tag:0]; 

 

这个库若想监听网络,必须先设置[socket readDataWithTimeout:-1 tag:0];这里面的tag很重要。如果你写的时候用的tag与读的不相同,那么永远在回调的地方没有回复。
当读的时候,需要判断长度是否足够,如果不够需要再次设置[socket readDataWithTimeout:-1 tag:0];
如果你需要保持这条链路,就不要用它的超时,因为默认超时,会断开连接。你再超时回调处,再次设置时间,也只是延长等待时间,到点仍是断链。

 

cilent向主机发送命令,每次发送一条后 主动断开

connectToHost:这个方法会返回一个bool  但是每次都返回yes   原因是这个方法yes  与no  表示 是否尝试着去链接host  并不代表是否链接成功

所以要想知道是否链接成功  要看是否调用了A方法

如果我们写如下的代码 

-(void)xxxxxxxxpressed:(xxx)xxxx{

 [socket  connectToHost:h onPort:p withTimeout:-1error:&error ];

 [socket  writeData:currentConmandwithTimeout:-1tag:button.tag];

[socket disconnectAfterWriting];

}

每次事件发生的时候  进行链接  并且马上发送数据,然后 等Writing结束后  撤销链接  这样在100%能链接上的情况下是没有问题的

但是 当主机出现问题  链接不上的时候, connectToHost:之后 马上写入数据,但是这个写入请求永远不会完成,所以之后的disconnectAfterWriting

一直会等待下去不执行,则这个connect仍然处于链接失败 状态。

当下一次事件发生的时候,会再次链接,这时程序崩溃,错误信息是告诉我们  必须先disconnect之后 才能再次链接

原因是 connect失败导致写入无法完成,所以disconnectAfterWriting 也就无法完成

解决办法 在 这个方法的最开始 加入几句代码

 [socketsetDelegate:nil];

        [socket disconnect];

        socket=nil;

然后每次都重新初始化一次socket即可





项目实战 二维码监听 付款成功:

import "AsyncSocket.h"


@interface YFScannerViewController ()<AsyncSocketDelegate>  {

    UIBarButtonItem *_rightItem;

    CGFloat _brightness;

    UIImageView *_imageView;

    

    NSTimer *_timer;

    NSInteger totalTime;

    

    AsyncSocket *_socket;

}


- (void)startSocket;

- (void)heartBeat;

- (void)getCode;


@end


@implementation YFScannerViewController





- (void)viewWillAppear:(BOOL)animated

{

    [[UIApplicationsharedApplication]setIdleTimerDisabled:YES];

    _brightness = [UIScreenmainScreen].brightness;

    [[UIScreenmainScreen]setBrightness:1.0f];

//     [_timer setFireDate:[NSDate distantPast]];

    [selfstartSocket];

//    [self getCode];

}


#pragma mark - Socket


//创建 socket连接

- (void)startSocket

{

    

    DLog(@"_socket.userData%ld",_socket.userData);

    if (!_socket)

        _socket = [[AsyncSocketalloc]initWithDelegate:self];

    

    [_socketconnectToHost:@"111.198.74.31"onPort:51066withTimeout:60error:nil];

    [_socketreadDataWithTimeout:-1tag:1000];

}


//读取连接成功之后的数据

- (void)heartBeat

{

    NSString *message = [NSStringstringWithFormat:@"0A10013D%@", [USER_DEFAULTobjectForKey:kUserId]];

    [_socketwriteData:[messagedataUsingEncoding:NSUTF8StringEncoding]withTimeout:60tag:2000];

    [selfperformSelector:@selector(heartBeat)withObject:nilafterDelay:30.0];

}


//断开 socket连接

- (void)socketDisconnect

{

    _socket.userData =SocketUsetData_Exit;

    [_socketdisconnect];

    _socket=nil;

}


//链接成功

- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port

{

    NSString *message = [NSStringstringWithFormat:@"0A10013E%@", [USER_DEFAULTobjectForKey:kUserId]];

    //读取数据

    [_socketwriteData:[messagedataUsingEncoding:NSUTF8StringEncoding]withTimeout:60tag:2000];

    

    [selfperformSelector:@selector(heartBeat)withObject:nilafterDelay:30.0];

}


- (void)onSocketDidDisconnect:(AsyncSocket *)sock

{

    [NSObjectcancelPreviousPerformRequestsWithTarget:selfselector:@selector(getCode)object:nil];

    [NSObjectcancelPreviousPerformRequestsWithTarget:selfselector:@selector(heartBeat)object:nil];

    [NSObjectcancelPreviousPerformRequestsWithTarget:selfselector:@selector(startSocket)object:nil];

    

    if (_socket.userData ==SocketUsetData_Exit)

        return;

    

    [selfperformSelector:@selector(startSocket)withObject:nilafterDelay:5.0];

}

//收到数据的时候调用


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

{

    NSString *key =@"123456781234567812345678";

    

    NSString *str = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding];

    str = [str stringByReplacingOccurrencesOfString:@"\n"withString:@""];

    str = [str stringByReplacingOccurrencesOfString:@"\r"withString:@""];

    NSArray *array = [strcomponentsSeparatedByString:@"|"];

    

    //此时其实网络监听已经完成了   若想继续监听  这个tag必须和之前的是一致的

    [_socketreadDataWithTimeout:-1tag:1000];

    

    if([arraycount] !=4)return ;

    

    NSString *receipt = [NSStringstringWithFormat:@"0A10102D%@", [arrayfirstObject]];

    [_socketwriteData:[receiptdataUsingEncoding:NSUTF8StringEncoding]withTimeout:60tag:2000];

    

    //解密

    NSMutableDictionary *dic = [[NSMutableDictionaryalloc]init];

    if ([[arrayobjectAtIndex:1]intValue] == 1)

    {

        YF_Pay_KaTool *tool = [[YF_Pay_KaToolalloc]init];

        NSData *_data = [[arrayobjectAtIndex:2]dataUsingEncoding:NSUTF8StringEncoding];

        _data = [tool.base64decode:_data];

        _data = [tool._3Desdecode:_datakey:key];

        dic = [NSJSONSerializationJSONObjectWithData:_dataoptions:0error:nil];

    }

    

  

    

    /*断开连接*/

    [selfperformSelector:@selector(socketDisconnect)withObject:nilafterDelay:2.0];

    

    YFPaySuccessViewController *vc =StoryboardName(@"YFPaySuccessViewController");

    YFPaySuccessModel *model = [[YFPaySuccessModelalloc]init];

    model.type =PayType_ToCode;

    

    model.bankBillNo = dic[@"orderNo"];

    model.bankAcctDate = dic[@"createTime"];

    model.bankReceiptNo = dic[@"cardNo"];

    model.payAmount = dic[@"orderPrice"];

    vc.model = model;

    [self.navigationControllerpushViewController:vcanimated:YES];

}


//离开界面的时候 去掉_socket连接

- (void)backBtnPressed

{

    [selfsocketDisconnect];

    [self.navigationControllerpopViewControllerAnimated:YES];

}





1 0
原创粉丝点击