AsyncSocket长连接棒包装问题解决

AsyncSocket长连接棒包装问题解决

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

project正在使用长连接快来server沟通。因此,指定我们的协议前两个字节为数据长度来区分数据包


app这边数据有两种传输形式:

1.app主动请求所须要的数据;

2.app异步接收来自服务端的推送消息,也就是app这边没有请求。服务端主动发送数据到appclient。


整个app执行期间,它们都是在同一个连接上完毕的传输数据。因此会出现下面的问题:

1.server传输数据过快,出现粘包的问题,比如

    1.1服务端一次发来多个推送消息;

    1.2网络不稳定,client连续发送多个请求client一次接收到所有答复。

2.client的一个请求报文,服务端的应答报文数据过大。到IP层须要进行分片,因此client这边就会出现几次才接收到完整的数据的情况;


首先有下面4个方法须要介绍

/**

 **实例方法

 **调用此方法以后,当套接字接收缓冲区有可用字节的时候。会触发onSocket:didReadData:withTag:托付方法。此时接收到的数据会出现上面说到的问题

 */

– (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag;


/**

 **实例方法

 **调用此方法以后。当套接字接收缓冲区有length长度的可用字节的时候,会触发onSocket:didReadData:withTag:托付方法,此时接收到固定长度的数据,这个固定长度就是length给出的值,当length的长度大于接收缓冲区数据的长度的时候,就会等待,直到接收到length长度的数据的时候才会触发以上托付方法的调用

 */

– (void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;


/**

 **实例方法

 **此方法功能同上,仅仅是多了几个參数buffer是你将接收的数据写到的地方,offset是写到buffer中的偏移位置

 */

– (void)readDataToLength:(NSUInteger)length

             withTimeout:(NSTimeInterval)timeout

                  buffer:(NSMutableData *)buffer

            bufferOffset:(NSUInteger)offset

                     tag:(long)tag;


/**

 **托付方法

 **此方法上面已经说到

 */

– (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)_data withTag:(long)tag。


解决方法:

client每次发送请求以后。首先仅仅接收两个字节的长度字节,例如以下:

[sendSocket readDataToLength:2 withTimeout:set.timeout tag:tag];[sendSocket writeData:data withTimeout:set.timeout tag:tag];

然后当有可用字节到达套接字接收缓冲区的时候触发下面托付方法,我们在里面做例如以下处理,这样既攻克了粘包的问题,也攻克了数据过大。多次接收完整的问题;

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)_data withTag:(long)tag
{
    SettingData* set = [SettingData shareSettingData];
    
    if (respondData == nil) {
        respondData = [[NSMutableData alloc]init];
        respondDataLen = [RequestUnit respondMessageLengthWithData:_data];
        [sock readDataToLength:respondDataLen withTimeout:set.timeout tag:tag];
        return;
    }
    [respondData appendData:[RequestUnit respondBytesToUTF8Data:_data]];
    [self parserData:respondData withTag:tag];
}



版权声明:本文博客原创文章。博客,未经同意,不得转载。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/117542.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • vs2017注释快捷键设置_vs注释多行代码快捷键

    vs2017注释快捷键设置_vs注释多行代码快捷键1、首先进入文件夹:C:\ProgramFiles(x86)\MicrosoftVisualStudio\2017\Community\Common7\IDE\VC\Snippets\2052\VisualC++2、在该文件夹中创建xxx.snippet文件,编辑内容如下:注:fuc是快捷方式<?xmlversion="1.0"encoding…

    2022年8月15日
    6
  • SQL中的聚合函数使用总结

    SQL中的聚合函数使用总结一般在书写sql的是时候很多时候会误将聚合函数放到where后面作为条件查询,事实证明这样是无法执行的,执行会报【此处不允许使用聚合函数】异常。为什么会报异常呢?其原因很简单:having放在groupby的后面 groupby后面只能放非聚合函数的列 where子句的作用是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,条件中不能包含聚组函数,使…

    2022年6月21日
    33
  • Dell服务器误删阵列恢复操作

    Dell服务器误删阵列恢复操作确认机器是否阵列(此例为阵列五)已丢失,然后配置idrac配置完成退出BIOS,让机器自然运行,进不去系统没关系正常磁盘掉线状态为Foreign,目前操作是误删了阵列所以磁盘全为ready模式,Foreign那块是后加的raid0(导回即可)这边机器退出BIOS开机以后,需要idrac收集一份日志(日志系统日志与存储日志)然后排查日志,发现日志有删除动作,但是没有格式化磁盘(应该是误删操作)在误删阵列,但是没有格式化的情况下啊,大概率实现资料恢复(先确认机器之前是什.

    2022年6月15日
    92
  • phpstorm IDEA 双击Shift键会弹出 SearchEverywhere 对话框,如何取消这个功能

    phpstorm IDEA 双击Shift键会弹出 SearchEverywhere 对话框,如何取消这个功能

    idea 2021年10月24日
    72
  • MariaDB安装教程(保姆级)

    MariaDB安装教程(保姆级)Maria的详细下载过程

    2022年6月12日
    133
  • sql2012安装错误代码0x84b10001_0x80300001安装错误

    sql2012安装错误代码0x84b10001_0x80300001安装错误”.”(十六进制值0x00)是无效字符。问题描述:Win7(SP1)卸载SQLServer2000后,先安装SQLSever2008,顺利完成,再安装SQLServer2014,各版本均提示”0x84B10001″错误。问题分析:检索相关网页,多认为Win7不能安装SQLServer2014企业版,只能安装开发版或标准版;有的认为操作系统语言版本要和SQLSever的

    2025年10月24日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号