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

网站推广的资源合作推广什么是网络营销的核心

网站推广的资源合作推广,什么是网络营销的核心,洛阳企业网站建设,网络规划设计师待遇怎么样1. TCP数据传输粘包简介 在本系列的第6篇文章《鸿蒙网络编程系列6-TCP数据粘包表现及原因分析》中,我们演示了TCP数据粘包的表现,如图所示: 随后解释了粘包背后的可能原因,并给出了解决TCP传输粘包问题的两种思路,第一…

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): Promise<void> {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/256771/

相关文章:

  • 网站素材 下载产品推广渠道
  • 网站后台维护怎么做seo专员工资一般多少
  • 中国网站推广黄页名录微商推广哪家好
  • 哈尔滨网站开发电话电商培训基地
  • 如何用php数据库做网站搜索seo优化托管
  • 中国城乡建设部人力网站首页优化落实疫情防控
  • 做网站到底能不能赚钱网络优化工程师前景
  • 乌镇网站建设标书百度站长工具域名查询
  • 制作公司网站价格腾讯广告代理商加盟
  • 大学生活动网站开发文案苏州seo门户网
  • 阿里云认证网站建设题库seo助理
  • 凤岗网站仿做靠谱seo外包定制
  • xampp安装wordpress说明徐州seo外包
  • 啥网站都能看的浏览器下载百度收录查询工具
  • 福田附近公司做网站建设哪家效益快奶糖 seo 博客
  • 临沂免费自助建站模板品牌整合营销
  • iis做本地视频网站找客户资源的网站
  • 做调查用哪个网站网络推广有多少种方法
  • 开发一个交易网站多少钱在线工具
  • 网站平台怎么建立的软文范例
  • 移动应用开发专业学什么东莞seo软件
  • 做宣传网站的公司手机百度极速版app下载安装
  • 私人可以做慈善网站吗外贸如何推广
  • 网站页面模板页面布局如何成为百度广告代理商
  • 瑞安外贸网站建设曲靖百度推广
  • 先做网站还是服务器销售营销方案100例
  • 用卫生纸做的礼物街网站免费网页空间到哪申请
  • 手游网站做cpc还是cpm广告号厦门网页搜索排名提升
  • 人个做外贸用什么网站好宁波百度seo点击软件
  • 诈骗网站怎么做的企业网站seo案例分析