易语言资源网 - 做最全的易语言资源下载社区
精易论坛授权登录

TCP粘包分包带校验并发处理   [复制链接]

    2021-01-08 08:36:54
    高级教程源码
    易语言资源网
    4721 次浏览
    来源链接


1.TCP是流传输,所以本质上不该称之为粘包,发送者和接收者都是自顾自的,要一段一段发得选UDP

现象是,你发出3个2048字节的包,发送时会被优化成4096/2048,或者跟之前的包合并,但是取出时却很随意,除了空载时的首个包,其他有可能拆成1-4096大小若干个包

2.“粘包”和“分包”很头疼,但是只要抓住第一个包,问题就解决了一大半

幸运的是,TCP发出的包不是乱序的,这有点像你按顺序写出字节集一样,只要你抓住头部的定义,就能轻而易举解构数据

为此,发送时,首个包要跟前一段数据流有时间间隔,好让之前的Recv操作完成(当然,条件允许可以Recv完成后反馈,发送端收到反馈消息再继续下一波)

3.定义协议结构,各有各的办法,以下代码仅作参考

.版本 2

    pocket = 取空白字节集 (#pk_size)

    DataAddr = 取变量指针 (pocket) + 8

    pk_sign = 取字节集数据 (到字节集 (“P_KT”), #整数型, )

    写数值ptr (DataAddr, #pk_sign, pk_sign)

    写数值ptr (DataAddr, #pk_crch, CRC32all)

    写数值ptr (DataAddr, #pk_crc32, CRC32all)

    写数值ptr (DataAddr, #pk_SN, 集_SN)

    写数值ptr (DataAddr, #pk_remain, size)

    CRC32pk = CRC32_PTR (DataAddr, #pk_size)

    写数值ptr (DataAddr, #pk_crch, CRC32pk)


4.使用哈希表存储分包数据

我认为哈希表存储的方式是线程安全的,客户句柄是唯一的,一个客户甚至分不到一条线程,该句柄对应的数据地址是唯一的,所以不会出现两条线程同时操作一个内存地址的情形

当然,出现碰撞时,插入链表这个操作不是线程安全的,这个以后优化

5.星光极速模块我只稍微改了一下,把原先字节集操作改成指针操作

6.没有选择HP-socket的原因是太庞大了,用来做服务端可以,但是如果作为客户端即使是静态库,编译之后也很大

7.目前涉分包组包的代码不多,其他的运用过程中不断改进


关于哈希表的部分,我专门开了个帖子

https://bbs.125.la/forum.php?mod=viewthread&tid=14659403



点我下载 (已有 246 次下载)

引用模块


源码文件名 模块文件名
分包组包.e
《星光极速》.ec


引用支持库


源码文件名 支持库文件名 支持库标识
分包组包.e 系统核心支持库 5.7 d09f2340818511d396f6aaf844c7e325
扩展界面支持库一 2.0 27bb20fdd3e145e4bee3db39ddd6e64c
扩展界面支持库二 2.0 AF6AD80AA4244A59AFB3D83ECF5173CC
星光极速6.88.6.e 系统核心支持库 5.7 d09f2340818511d396f6aaf844c7e325
扩展界面支持库二 2.0 AF6AD80AA4244A59AFB3D83ECF5173CC
扩展界面支持库一 2.0 27bb20fdd3e145e4bee3db39ddd6e64c
特殊功能支持库 3.1 A512548E76954B6E92C21055517615B0
应用接口支持库 3.1 F7FC1AE45C5C4758AF03EF19F18A395D
超文本浏览框支持库 2.2 5014D8FA6DCA40b68FA626D8183666EB


[错误报告]   上一篇:动态菜单模块支持无限嵌套...     下一篇:易语言做WEBUI第四版...