当前位置: 首页 > news >正文

迅美网站建设佛山企业制作网站

迅美网站建设,佛山企业制作网站,权威的公司网站制作,亚网互联网站设计1. TCP数据传输粘包简介 在本系列的第6篇文章《鸿蒙网络编程系列6-TCP数据粘包表现及原因分析》中#xff0c;我们演示了TCP数据粘包的表现#xff0c;如图所示#xff1a; 随后解释了粘包背后的可能原因#xff0c;并给出了解决TCP传输粘包问题的两种思路#xff0c;第一…1. TCP数据传输粘包简介 在本系列的第6篇文章《鸿蒙网络编程系列6-TCP数据粘包表现及原因分析》中我们演示了TCP数据粘包的表现如图所示 随后解释了粘包背后的可能原因并给出了解决TCP传输粘包问题的两种思路第一种是指定数据包结束标志在本系列第35篇《鸿蒙网络编程系列35-通过数据包结束标志解决TCP粘包问题》中给出了具体的实现第二种是通过固定包头指定包的长度本文将通过一个示例演示这种思路的实现。 2. 固定包头可变包体解决TCP粘包问题演示 本示例运行后的界面如图所示 和上一篇文章类似输入服务端的地址这里可以使用本系列第25篇文章《鸿蒙网络编程系列25-TCP回声服务器的实现》中创建的TCP回声服务器也可以使用其他类似的回声服务器然后输入服务器端口最后单击测试按钮循环发送0到99的数字字符串到服务端服务端会回传收到的信息本示例在收到服务器信息后在日志区域输出如图所示 从中可以看出这次也彻底解决了数据粘包问题收到的信息和发送时保持一致。 3. 固定包头可变包体解决TCP粘包问题示例编写 下面详细介绍创建该示例的步骤。 步骤1创建Empty Ability项目。 步骤2在module.json5配置文件加上对权限的声明 requestPermissions: [{name: ohos.permission.INTERNET}]这里添加了访问互联网的权限。 步骤3在Index.ets文件里添加如下的代码 import { socket } from kit.NetworkKit; import { Decimal, util, buffer } from kit.ArkTS; import { BusinessError } from kit.BasicServicesKit;Entry Component struct Index {State title: string 固定包头可变包体演示示例;//服务端端口号State port: number 9990//服务端IP地址State serverIp: string //操作日志State msgHistory: string //最大缓存长度maxBufSize: number 1024 * 8//接收数据缓冲区receivedDataBuf: buffer.Buffer buffer.alloc(this.maxBufSize)//缓冲区已使用长度receivedDataLen: number 0//日志显示区域的滚动容器scroller: Scroller new Scroller()build() {Row() {Column() {Text(this.title).fontSize(14).fontWeight(FontWeight.Bold).width(100%).textAlign(TextAlign.Center).padding(10)Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {Text(服务端地址:).fontSize(14).width(90)TextInput({ text: this.serverIp }).onChange((value) {this.serverIp value}).height(40).width(80).fontSize(14).flexGrow(1)Text(:).fontSize(14)TextInput({ text: this.port.toString() }).onChange((value) {this.port parseInt(value)}).height(40).width(70).fontSize(14)Button(测试).onClick(() {this.test()}).height(40).width(60).fontSize(14)}.width(100%).padding(10)Scroll(this.scroller) {Text(this.msgHistory).textAlign(TextAlign.Start).padding(10).width(100%).backgroundColor(0xeeeeee)}.align(Alignment.Top).backgroundColor(0xeeeeee).height(300).flexGrow(1).scrollable(ScrollDirection.Vertical).scrollBar(BarState.On).scrollBarWidth(20)}.width(100%).justifyContent(FlexAlign.Start).height(100%)}.height(100%)}//测试async test() {//服务端地址let serverAddress: socket.NetAddress { address: this.serverIp, port: this.port, family: 1 }//执行TCP通讯的对象let tcpSocket: socket.TCPSocket socket.constructTCPSocketInstance()//收到消息时的处理tcpSocket.on(message, (value: socket.SocketMessageInfo) {this.receiveMsgFromServer(value)})await tcpSocket.connect({ address: serverAddress }).then(() {this.msgHistory 连接成功\r\n;}).catch((e: BusinessError) {this.msgHistory 连接失败 ${e.message} \r\n;})//循环发送0到99的数字字符串到服务端for (let i 0; i 100; i) {let msg i.toString()await this.sendMsg2Server(tcpSocket, msg)let sleepTime Decimal.random().toNumber() 0.5//休眠sleepTime时间大概0.5毫秒到1.5毫秒await sleep(sleepTime)}}//发送数据到服务端async sendMsg2Server(tcpSocket: socket.TCPSocket, msg: string) {let textEncoder new util.TextEncoder();let encodeValue textEncoder.encodeInto(msg)let sendBuf buffer.alloc(2 encodeValue.byteLength)//写入固定包头中的长度信息sendBuf.writeUInt16LE(encodeValue.byteLength)//写入可变包体信息sendBuf.write(msg, 2)await tcpSocket.send({ data: sendBuf.buffer })}//读取服务端发送过来的数据receiveMsgFromServer(value: socket.SocketMessageInfo) {//把接收到的数据复制到缓冲区有效数据尾部let copyCount buffer.from(value.message).copy(this.receivedDataBuf, this.receivedDataLen)this.receivedDataLen copyCount//至少写入了3个字节才需要解析if (this.receivedDataLen 3) {return;}//当前数据包长度let packLen this.receivedDataBuf.readUInt16LE()let textDecoder util.TextDecoder.create(utf-8);//当前数据包长度加上固定包体的2字节如果小于等于缓冲区已使用长度就可以解析while ((packLen 2) this.receivedDataLen) {//把可变包体中的数据转换为字符串let msgArray new Uint8Array(this.receivedDataBuf.subarray(2, packLen 2).buffer);let msg textDecoder.decodeToString(msgArray)//剩余的未解析数据let leaveBufData this.receivedDataBuf.subarray(packLen 2, this.receivedDataLen)//剩余的未解析数据移动到缓冲区头部for (let pos 0; pos leaveBufData.length; pos) {this.receivedDataBuf.writeUInt8(leaveBufData.readUInt8(pos), pos)}//重新设置缓冲区已使用长度this.receivedDataLen leaveBufData.length//输出接收的数据到日志this.msgHistory S: msg \r\n//至少写入了3个字节才需要解析否则跳出循环if (this.receivedDataLen 3) {break;}//开始查找下一个固定包头中的可变包体长度packLen this.receivedDataBuf.readUInt16LE()}this.scroller.scrollEdge(Edge.Bottom)} }//休眠指定的毫秒数 function sleep(time: number): Promisevoid {return new Promise((resolve) setTimeout(resolve, time)); }步骤4编译运行可以使用模拟器或者真机。 步骤5按照本文第2部分“数据包结束标志解决TCP粘包问题演示”操作即可。 4. 代码分析 本示例的关键点在于构造数据包的格式具体数据包的格式是这样的前两个字节为固定的包长度使用小端的16位无符号整数表示后面是包内容。以发送数据包为例代码如下所示 async sendMsg2Server(tcpSocket: socket.TCPSocket, msg: string) {let textEncoder new util.TextEncoder();let encodeValue textEncoder.encodeInto(msg)let sendBuf buffer.alloc(2 encodeValue.byteLength)//写入固定包头中的长度信息sendBuf.writeUInt16LE(encodeValue.byteLength)//写入可变包体信息sendBuf.write(msg, 2)await tcpSocket.send({ data: sendBuf.buffer })}这里首先把要发送的内容编码为Uint8Array类型然后为缓冲区分配长度长度为内容编码后的长度加上2随后把内容长度作为无符号数写入缓冲区然后把发送的内容也写入缓冲区最后使用TCP客户端发送缓冲区到服务端。 接收时首先把所有收到的数据都复制到接收缓冲区中然后从缓冲区头部取两个字节作为数据包内容长度然后判断接收缓冲区中已接收的数据是不是大于等于数据包内容长度加2如果是说明接收到了完整的数据包就可以从中提取内容了提取完毕把剩下的缓冲区数据移动到缓冲区头部继续下一次循环从缓冲区中提取完整数据包的数据知道已接收的缓冲区小于数据包长度加2为止。相关代码位于方法receiveMsgFromServer中源码包含了详细的注释这里就不再赘述了。 本文作者原创除非明确授权禁止转载 本文源码地址 https://gitee.com/zl3624/harmonyos_network_samples/tree/master/code/tcp/PacketHeadWithLen 本系列源码地址 https://gitee.com/zl3624/harmonyos_network_samples
http://www.hkea.cn/news/14287750/

相关文章:

  • 网页设计网站设计哪个好网站建设费 科目
  • 宁津县建设局网站金华专业网站制作
  • 在哪个网站做推广好注册公司分类大全
  • 网站技术制作流程图ICP备案域名网站
  • 医院网站建设步骤php wordpress 开源
  • 网站流量分析指标网络教学平台昆明理工大学
  • 做网站都需要什么软件上海境外输入
  • 手机版网站开发公司网站建设功能模块几报价
  • 网站关键词排名不稳定网站空间托管
  • 网站专题页做多大尺寸设计商标
  • 用rp怎么做网站按钮下拉菜单wordpress 主题demo
  • 昆明网络推广招聘搜索引擎优化策略应该包括
  • 惠州顺德网站建设wordpress去主题插件提示
  • 网站后台管理系统设计网站建设国家标准
  • 建设网站要在需求服务app开发的公司
  • 网站备案幕布要求网络营销的六个特点
  • 模块网站中山网站制作专业
  • 深圳市公司网站建设企业管理学习网站
  • 手机做logo用什么网站wordpress+制作首页模板下载
  • 深圳网站建设电话阳江房产网上半年海怡新
  • 杭州做网站外包公司北京海岸设计公司网站
  • phpok做网站教程wordpress 分类子类
  • 网站域名申请怎么做四川城乡住房建设厅官方网站
  • 中山建公司网站智能城市 电子商务网站建设
  • 做网站时随便弄上去的文章怎么删掉网站视频播放器用什么做的
  • 全美东莞网站建设网站建设合同法
  • 网站建设专题页面当地的建设工程信息网
  • iis7如何部署网站国内比较大的源码网站
  • 郑州网站建设选微锐x域名持有者个人可以做公司网站
  • 做网站要先买域名吗生产网线需要什么设备