AsyncSocket长连接棒包装问题解决

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];
}

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

时间: 2024-10-05 22:58:00

AsyncSocket长连接棒包装问题解决的相关文章

AsyncSocket长连接粘包问题解决方案

工程中使用长连接来和服务器进行通讯,因此,我们的协议通过指定前两个字节为数据长度来区分数据包 app这边数据有两种传输形式: 1.app主动请求所需要的数据: 2.app异步接收来自服务端的推送消息,也就是app这边没有请求,服务端主动发送数据到app客户端: 整个app运行期间,它们都是在同一个连接上完成的数据传输,因此会出现以下的问题: 1.服务器数据传输过快,出现粘包的问题,例如 1.1服务端一次发来多个推送消息: 1.2网络不稳定,客户端连续发送多个请求客户端一次接收到全部答复: 2.客

ERROR 2049 (HY000): Connection using old (pre-4.1.1)

测试环境新装了MySQL服务器,在登陆时无法成功登陆.其提示为使用的旧的认证协议而被拒绝.其具体的错误提示为ERROR 2049 (HY000): Connection using old (pre-4.1.1) authentication protocol refused (client option 'secure_auth' enabled)以下是关于这个问题的描述及其解决方案,供大家参考. 1.故障现象[[email protected] ~]# mysqladmin -u root

java变参

java变参是通过数组来实现的 Object[] addAll(Object[] array1, Object... array2)和Object[] addAll(Object[] array1, Object[] array2)签名应该一致的. public class ArrayUtils { // Clone // ----------------------------------------------------------------------- /** * <p> * Sh

js 难点之call,apply,bind实现

call 一句话介绍 call: call() 方法在使用一个指定的 this 值和若干个指定的参数值的前提下调用某个函数或方法. 举个例子: var foo = { value: 1 }; function bar() { console.log(this.value); } bar.call(foo); // 1 注意两点: call 改变了 this 的指向,指向到 foo bar 函数执行了 模拟实现第一步 那么我们该怎么模拟实现这两个效果呢? 试想当调用 call 的时候,把 foo

Delphi - Indy TIdHTTP方式创建程序外壳 - 实现可执行程序的自动升级

Delphi 实现可执行程序的自动升级 准备工作: 1:Delphi调用TIdHTTP方式开发程序,生成程序打包外壳 说明:程序工程命名为ERP_Update 界面布局如下: 代码实现如下: 1 unit Unit1; 2 3 interface 4 5 uses 6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 7 Dialogs, StdCtrls, ExtCtrls, 8 IdTCPCo

Nginx与Tomcat、Client之间请求的长连接配置不一致问题解决[转]

http://bert82503.iteye.com/blog/2152613 前些天,线上出现“服务端长连接与客户端短连接引起Nginx的Writing.Active连接数过高问题”,这个是由于“服务端使用HTTPs长连接,而客户端使用短连接”引起.这几天,发现Nginx与Tomcat之间也存在同样的问题,原因是两边的相关配置参数不一致引起的.(这是心细活!) 先说说服务为什么使用HTTPs长连接技术?有如下几个原因: 对响应时间要求较高: 服务走的是公网,客户端与服务端的TCP建立的三次握手

mysql 导出过长的数字列时变科学计数法问题解决办法

--mysql 导出数据时,  数字类型的列如果位数过长,变为科学技术发问题 concat('\t',a.IDCARD_NO) 例子: select   concat('\t',a.IDCARD_NO)   from   表a  as  a

MySQL中使用group_concat()函数数据字符过长报错的问题解决方法

最近在办公软件项目,在开发权限指标遇到一个问题:我们系统的一些逻辑处理是用存储过程实现的,但是有一天客户反馈说权限指标分配报错,查了分配的权限数据牵扯到的数据权限基础资源,没有问题.权限指标分配的存储过程中有这样两句代码: SET @tests = '';SELECTGROUP_CONCAT( DISTINCT REPLACE ( concat( '''', ( indicator_content ), '''' ), ',', ''',''' ))AS Allnumber INTO @test

Anroid关于fragment控件设置长按事件无法弹出Popupwindows控件问题解决记录

一.问题描述 ????记录一下最近在安卓的gragment控件中设置长按事件遇见的一个坑!!! ????在正常的activity中整个活动中设置长按事件我通常实例化根部局,例如LinearLayout longSetting = (LinearLayout) view.findViewById(R.id.testlong);,然后对变量longSetting调用setOnLongClickListener函数实现注册长按事件,但是在一个fragment控件中如此设置长按无法弹出popupwind