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];
}
版权声明:本文博客原创文章。博客,未经同意,不得转载。
AsyncSocket长连接棒包装问题解决的更多相关文章
- jquery异步ajax超大长度base64图片长字段数据传输问题解决办法和php后台处理办法
2017年5月9日19:25:02 在做在线签名的时候,到了图片上传的时候,使用jquery异步ajax上传base64的图片数据的时候,使用默认的方式进行数据传输偶尔会出现 生产的图片只有上半部分, ...
- Android Base64图片无法长按保存 问题解决
踩了一个巨坑. 目前微信ios/android 均能长按保存src=base64的图片 (微信android x5 专门解决了这个问题); 但是android其他App没有针对解决这个系统问题(姑且 ...
- lvs 会话保持(转发)
lvs & keepalived的tcp 长连接的问题解决办法 虽然应用keepalived搞定了后端服务负载均衡和高可用性问题,但是在具体应用的时候,还是要注意很多问题.很多应用都用tcp或 ...
- JavaScript深入之call和apply的模拟实现
call 一句话介绍 call: call() 方法在使用一个指定的 this 值和若干个指定的参数值的前提下调用某个函数或方法. 举个例子: var foo = { value: 1 }; func ...
- TCP|UDP|Http|Socket
TCP_IP.Http.Socket的区别 - 计算机网络知识库 iOS-Socket网络通信-框架与API - 简书 CocoaAsyncSocket + Protobuf 处理粘包和拆包问题 - ...
- java变参
java变参是通过数组来实现的 Object[] addAll(Object[] array1, Object... array2)和Object[] addAll(Object[] array1, ...
- 毕设三: spark与phoenix集成插入数据/解析json数组
需求:将前些日子采集的评论存储到hbase中 思路: 先用fastjson解析评论,然后构造rdd,最后使用spark与phoenix交互,把数据存储到hbase中 部分数据: [ { "r ...
- Delphi - Indy TIdHTTP方式创建程序外壳 - 实现可执行程序的自动升级
Delphi 实现可执行程序的自动升级 准备工作: 1:Delphi调用TIdHTTP方式开发程序,生成程序打包外壳 说明:程序工程命名为ERP_Update 界面布局如下: 代码实现如下: unit ...
- call和apply的模拟实现
call 一句话介绍 call: call() 方法在使用一个指定的 this 值和若干个指定的参数值的前提下调用某个函数或方法. 举个例子: var foo = { value: 1 }; func ...
随机推荐
- STL之Vector(不定长数组)
vector是同一种对象的集合,每一个对象都有一个相应的整数索引值.和string对象一样,标准库将负责管理与存储元素相关的类存. 引入头文件 #include<vector> 1.vec ...
- js使用栈来实现10进制转8进制 js取除数 余数
function ten2eight(x){ var s=[]; var r=''; while(x>0){ s.push(x%8); x=parseInt(x/8); } while(s.le ...
- java+mysql对于表情的处理
环境错误: mysql 5.0: utf8编码 jdbc:mysql-connector-java-5.1.5-bin.jar 情符的情况下报错: java.sql.SQLException: Inc ...
- Linux scp文件复制
scp是 secure copy的缩写, scp是linux系统下基于ssh登陆进行安全的远程文件拷贝命令. 1.scp命令的用处: scp在网络上不同的主机之间复制文件,它使用ssh安全协议传输 ...
- SE 2014年5月8日
两企业接入到 Internet(A公司和B公司),企业内部的用户及服务器均能够访问到 Internet. 2. A公司规模较大,采用了接入层/汇聚层/核心层的划分模式,接入层划分了多vLan(如图), ...
- Get与Post的差别
Http定义了与server交互的不同方法,最主要的方法有4种,各自是GET,POST.PUT,DELETE. URL全称是资源描写叙述符.我们能够这样觉得:一个URL地址,它用于描写叙述一个网络上的 ...
- javaScript滚动新闻
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...
- xpages的comboBox能够手动输入
在xpages使用的comboBox默认仅仅能选择.不能手动输入,怎么才干手动输入呢?经过查找资料和測试,最终能够了,请大家能够试试 假设试不行,能够再下载demo http://download.c ...
- Java命令参数说明
Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令 JAVA_HOME"bin"java –option 来启动,-option为虚 ...
- C++经典面试题(二)
近期看一些面试题,认为假设自己被问到了,并不能非常利落的回答出来. 一是从来没有这个意识,二是没有认真的梳理下. 以下对这些题做出分析,哈!个人能力有限,当中难免有疏漏,欢迎大家补充咯. 11.引用与 ...