IOS 详解socket编程[oc]粘包、半包处理
发布时间 - 2026-01-10 22:59:31 点击率:次IOS 详解socket编程[oc]粘包、半包处理

在做socket编程时,如果是做tcp连接,那就不可避免的会遇到粘包与半包的问题,粘包就是多组数据被一并接收了,粘在了一起,无法做划分;半包就是有数据接收不完整,无法处理。要解决粘包、半包的问题,一般在设计数据(消息)格式时会约定好一个字段专门用于描述数据包的长度,这样就使数据有了边界,依靠这个边界,就能把每组数据划分出来,数据不完整时也能获知数据的缺失。
(当然也可以把数据设计成定长数据,但这样不够灵活;或者用\n,\r这类字符作为数据划分依据,但不直观、不明确,同时也不灵活)
举个栗子:
消息=消息头+消息体。消息头用于描述消息本身的基本信息,消息体则为消息的具体内容
如上图所示,假如我们的一个消息是这么定义的
消息头 = msgId(4B)+version(2B)+len(4B),共占用10字节
消息体 = len中描述的16字节长
所以这条消息的长度就是 26字节
可以看到,要想知道一条完整数据的边界,关键就是消息头中的len字段
假如我们现在接收到的数据是这样的:
这个情况下即包含了粘包,也出现了半包的情况,三个数据包粘在了一起,最后一个数据包没有接收完全,出现了半包的情况,看看代码如何处理
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
while (_readBuf.length >= 10)//因为头部固定10个字节,数据长度至少要大于10个字节,我们才能得到完整的消息描述信息
{
NSData *head = [_readBuf subdataWithRange:NSMakeRange(0, 10)];//取得头部数据
NSData *lengthData = [head subdataWithRange:NSMakeRange(6, 4)];//取得长度数据
NSInteger length = [[[NSString alloc] initWithData:lengthData encoding:NSUTF8StringEncoding] integerValue];//得出内容长度
NSInteger complateDataLength = length + 10;//算出一个包完整的长度(内容长度+头长度)
if (_readBuf.length >= complateDataLength)//如果缓存中数据够一个整包的长度
{
NSData *data = [_readBuf subdataWithRange:NSMakeRange(0, complateDataLength)];//截取一个包的长度(处理粘包)
[self handleTcpResponseData:data];//处理包数据
//从缓存中截掉处理完的数据,继续循环
_readBuf = [NSMutableData dataWithData:[_readBuf subdataWithRange:NSMakeRange(complateDataLength, _readBuf.length - complateDataLength)]];
}
else//如果缓存中的数据长度不够一个包的长度,则包不完整(处理半包,继续读取)
{
[_socket readDataWithTimeout:-1 buffer:_readBuf bufferOffset:_readBuf.length tag:0];//继续读取数据
return;
}
}
//缓存中数据都处理完了,继续读取新数据
[_socket readDataWithTimeout:-1 buffer:_readBuf bufferOffset:_readBuf.length tag:0];//继续读取数据
}
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
# IOS
# 详解socket编程[oc]粘包、半包处理
# socket
# socket编程
# iOS开发项目- 基于WebSocket的聊天通讯(2)
# iOS开发项目- 基于WebSocket的聊天通讯(1)
# IOS开发网络篇—Socket编程详解
# iOS App通信之local socket示例
# iOS App之间的通信 local socket
# iOS应用中使用AsyncSocket库处理Socket通信的用法讲解
# IOS中使用 CocoaAsyncSocket
# iOS 使用 socket 实现即时通信示例(非第三方库)
# 数据包
# 不完整
# 出现了
# 定长
# 也不
# 那就
# 就能
# 是这样
# 也能
# 这条
# 这类
# 希望能
# 要想
# 可以看到
# 我们现在
# 不可避免
# 所示
# 谢谢大家
# 但不
# 则为
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Firefox Developer Edition开发者版本入口
今日头条AI怎样推荐抢票工具_今日头条AI抢票工具推荐算法与筛选【技巧】
猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?
Laravel如何使用withoutEvents方法临时禁用模型事件
香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南
Chrome浏览器标签页分组怎么用_谷歌浏览器整理标签页技巧【效率】
制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?
如何在宝塔面板中创建新站点?
Laravel如何为API生成Swagger或OpenAPI文档
*服务器网站为何频现安全漏洞?
Windows10怎样连接蓝牙设备_Windows10蓝牙连接步骤【教程】
如何在阿里云虚拟主机上快速搭建个人网站?
网站制作软件有哪些,制图软件有哪些?
微信推文制作网站有哪些,怎么做微信推文,急?
浅谈javascript alert和confirm的美化
北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?
Laravel怎么导出Excel文件_Laravel Excel插件使用教程
JavaScript实现Fly Bird小游戏
Laravel如何部署到服务器_线上部署Laravel项目的完整流程与步骤
深圳网站制作平台,深圳市做网站好的公司有哪些?
Laravel如何获取当前登录用户信息_Laravel Auth门面使用与Session用户读取【技巧】
Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践
如何用IIS7快速搭建并优化网站站点?
如何在 Telegram Web View(iOS)中防止键盘遮挡底部输入框
在Oracle关闭情况下如何修改spfile的参数
青岛网站建设如何选择本地服务器?
Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南
Laravel如何实现全文搜索功能?(Scout和Algolia示例)
微信小程序 require机制详解及实例代码
如何在阿里云购买域名并搭建网站?
如何快速生成专业多端适配建站电话?
Laravel怎么在Controller之外的地方验证数据
Laravel如何使用Blade组件和插槽?(Component代码示例)
Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?
Laravel如何使用Gate和Policy进行授权?(权限控制)
Laravel请求验证怎么写_Laravel Validator自定义表单验证规则教程
Laravel怎么生成二维码图片_Laravel集成Simple-QrCode扩展包与参数设置【实战】
b2c电商网站制作流程,b2c水平综合的电商平台?
如何基于云服务器快速搭建网站及云盘系统?
如何快速搭建FTP站点实现文件共享?
Laravel模型关联查询教程_Laravel Eloquent一对多关联写法
详解jQuery中基本的动画方法
武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?
香港服务器租用每月最低只需15元?
Laravel定时任务怎么设置_Laravel Crontab调度器配置
HTML5段落标签p和br怎么选_文本排版常用标签对比【解答】
桂林网站制作公司有哪些,桂林马拉松怎么报名?
高性能网站服务器部署指南:稳定运行与安全配置优化方案
微信小程序 wx.uploadFile无法上传解决办法
Python并发异常传播_错误处理解析【教程】

