易语言实现TCP粘包分包带校验的并发处理方法

需积分: 10 1 下载量 96 浏览量 更新于2024-11-17 收藏 62KB ZIP 举报
资源摘要信息:"TCP粘包分包带校验并发处理-易语言" 易语言是一种中文编程语言,专门针对中文用户设计,以其简洁易学的特点受到中文编程爱好者的青睐。在处理TCP通信时,由于TCP是面向流的协议,数据是连续传输的,因此在发送和接收端可能会出现粘包和分包的情况。粘包是指多个数据包被组合到一起发送或接收,分包则是指一个数据包被拆分成多个包发送或接收。这对于编程来说,处理不当会造成数据接收错误。 1. TCP粘包分包问题 由于TCP协议是基于流的,它不保证数据包的边界,所以不存在真正的"粘包"概念,但会出现发送时数据包被优化合并,而在接收时数据包被随意拆分的现象。为了解决这个问题,可以设计协议结构来区分不同数据包的边界。发送方在发送数据时,应确保每个数据包有明确的起始和结束标志,或者在发送数据时,首个数据包与前一个数据包之间有足够的时间间隔,以便接收方完成之前的接收操作。 2. 协议结构设计 在易语言中设计协议结构,主要是为了确保数据的完整性和校验。通过在数据包的特定位置定义校验字段,接收方可以通过校验算法(如CRC32)来验证数据的完整性。这要求发送方在发送数据包前计算校验值,并将其加入到数据包中,接收方在接收到数据包后进行同样的校验计算,并与接收到的校验值进行对比,以确保数据未被篡改。 3. 使用哈希表存储分包数据 使用哈希表来存储分包数据是一种有效的方法,它能够提供较快的数据访问速度和线程安全的存储环境。在易语言中,通过为每个客户端创建一个唯一的句柄,可以将分包数据存储在哈希表中,确保即使在多线程环境下,每个句柄的数据也是独立的。但需要注意的是,当出现哈希冲突时,插入链表的操作并不是线程安全的,因此需要进行相应的优化处理。 4. 星光极速模块 星光极速模块是一个易语言的模块,用于改进字节集操作的效率。作者提到了将字节集操作改为指针操作的改进,这可能是为了提高数据处理的速度和效率。在编程中,指针的使用可以提高对内存的直接操作能力,但同时也需要更加小心地管理内存,以避免内存泄漏等问题。 5. HP-socket的选择 HP-socket是一个功能强大的网络编程组件,但它因为功能丰富而体积较大。作者认为,如果仅仅需要作为客户端使用,HP-socket的体积可能过大,尤其是在静态库的情况下,编译后的体积也会变大。因此,作者没有选择HP-socket,而是选择了更适合当前项目需求的解决方案。 6. 实践中的持续改进 作者提到,当前涉及分包组包的代码还不是很多,但在实际的应用过程中会不断进行改进。这体现了软件开发中的迭代思想,即在软件开发和运行过程中不断根据实际需要进行调整和优化。 关于哈希表的使用,作者专门开了一个帖子进行详细讨论,这个帖子链接为***,提供了更深入的探讨和交流。 综上所述,这个资源摘要信息主要涵盖了TCP粘包分包问题的处理、协议结构设计、哈希表在存储分包数据中的应用、星光极速模块的使用、HP-socket的选择以及代码优化的持续实践等多个方面,为易语言开发者在进行TCP网络编程时提供了有价值的参考和解决方案。
2019-08-23 上传
.版本 2 .支持库 spec .支持库 sock .程序集 窗口程序集_启动窗口 .子程序 _按钮2_被单击 客户1.发送数据 (取重复字节集 (10000, 到字节集 (“1”)) + 到字节集 (“分隔符”)) 客户1.发送数据 (取重复字节集 (20000, 到字节集 (“2”)) + 到字节集 (“分隔符”)) 客户1.发送数据 (取重复字节集 (30000, 到字节集 (“3”)) + 到字节集 (“分隔符”)) 客户1.发送数据 (取重复字节集 (40000, 到字节集 (“4”)) + 到字节集 (“分隔符”)) 客户1.发送数据 (取重复字节集 (50000, 到字节集 (“5”)) + 到字节集 (“分隔符”)) 客户1.发送数据 (取重复字节集 (60000, 到字节集 (“6”)) + 到字节集 (“分隔符”)) 客户1.发送数据 (取重复字节集 (70000, 到字节集 (“7”)) + 到字节集 (“分隔符”)) 客户1.发送数据 (取重复字节集 (80000, 到字节集 (“8”)) + 到字节集 (“分隔符”)) 客户1.发送数据 (取重复字节集 (90000, 到字节集 (“9”)) + 到字节集 (“分隔符”)) 客户1.发送数据 (取重复字节集 (100000, 到字节集 (“0”)) + 到字节集 (“结尾符”)) .子程序 _服务器1_数据到达 .局部变量 取回数据, 字节集 .局部变量 数据数组, 文本型, , "0" .局部变量 次数, 整数型 .局部变量 临时数据, 字节集, 静态 .局部变量 得到的封包, 文本型 取回数据 = 服务器1.取回数据 () .判断开始 (取字节集右边 (取回数据, 6) ≠ 到字节集 (“结尾符”))  ' 6为结尾符的长度;这里检测封包是否全部发送完毕,如果没有发送完毕就会把发送来的封包数据进行累加     临时数据 = 临时数据 + 取回数据 .默认     临时数据 = 临时数据 + 取回数据  ' 检测到结尾符出现,说明数据已经发送完毕,这里把最后发送来的带有结尾符的数据加上就OK了。     临时数据 = 子字节集替换 (临时数据, 到字节集 (“结尾符”), , 取字节集长度 (临时数据) - 6, 6)  ' 6为结尾符的长度;这里把结尾符替换尾空,剩余数据尾完整的纯净数据。     数据数组 = 分割文本 (到文本 (临时数据), “分隔符”, )  ' 这里把收到的数据进行分割处理,无论服务器发送了多少次,都统一按分隔符分割     调试输出 (“封包数量:” + 到文本 (取数组成员数 (数据数组)))     .计次循环首 (取数组成员数 (数据数组), 次数)         得到的封包 = 数据数组 [次数]  ' 这里得到分割后的封包文本。         调试输出 (“第” + 到文本 (次数) + “个封包的大小:” + 到文本 (取文本长度 (得到的封包)))  ' 这里的大小和上面发送封包的大小相同,可以看到封包的分割次数。     .计次循环尾 ()     临时数据 = {  } .判断结束 .子程序 __启动窗口_创建完毕 客户1.连接 (取本机名 (), 8888)