一、目录结构介绍
—DOC:目录下是官方提供的文档,包括Development Guide
—DotNet:.net项目的开发步骤,可以直接通过nuget部署HPsocket.net
—Linux:Linux的工程,包括android build
—MacOS:mac环境的开发步骤
—Windows:Windows的工程,最常用的开发环境
--Bin:编译好的dll和lib
--Demo:官方提供的使用示例,包括PUSH模型示例、 PULL模型示例、 PACK模型示例、 性能测试示例以及其它编程语言示例
--Project:项目的VS工程
--Include:使用HP-Socket库需要的头文件
--Src是核心功能源代码,Project只是工程,源代码在这里
--Common是通用功能源代码
--Other Languages 其他语言项目地址
目前支持Windows & Linux平台
二、模型选取
2.1 什么是粘包,断包
由于TCP是流式套接字,所以socket收到的数据而言,可能不是一个完整的包或者粘包了。此时需要应用层来进行拆包组包了。例如客户端连续发送了三个数据包大小分别是:300,500,100。但是接收端接受到的数据可能是200,400,100,200。所以此时我们处理接收到的数据就要进行组包和拆包了。
由于200不足一个数据包,所以需要组合下一个数据包400。此时数据大小为600,但是客户端第一个发送的数据包是300,所以此时需要将600拆分为300+300。此时就可以得到第一个数据包300,剩余数据300,但是第二个数据包是500。数据不够所以需要组合下一个数据100总共数据400,依然不够一个包,继续组包剩余的200,此时接受数据600,足够一个数据包500,所以将600拆解为500+100。得到第二个数据包500,剩余数据100,正好和第三个数据包100匹配。此时数据包解析完毕。基本逻辑
while(true)
{
data_size = recv_data();
if(data_size < 数据包长度)
continue;//继续接受数据
///循环拆包,当不够一个包的时候继续接受数据等待一个完整的包
while(true)
{
//足够包长度,拆包
data_size -= 数据包长度;
//更新数据缓冲区,处理包
hanle_pack(pack);
if(data_size < 数据包长度)
break;
}
}
2.2 Hp-Socket提供的3种接收模型
HP-Socket 提供 PUSH / PULL / PACK 等接收模型,应用程序可以灵活选择以手工方式、半自动方式或全自动方式处理封解包。
接收模型 | 接收事件 | 说明 |
---|---|---|
PUSH | OnReceive(pSender, dwConnID, pData, iLength) | 手工方式/原生方式 |
PULL | OnReceive(pSender, dwConnID, iLength) | 半自动 |
PACK | OnReceive(pSender, dwConnID, pData, iLength) | 全自动 |
-
PUSH 模型组件触发监听器对象的 OnReceive(pSender, dwConnID, pData, iLength)
事件时,应用程序需要立即处理接收到的数据,如:粘包处理、协议解析等。组件
不会对应用层的数据处理工作提供任何协助。 -
PULL 模型组件触发监听器对象的 OnReceive(pSender, dwConnID, iTotalLength) 事
件时,应用程序根据应用层协议检测接收到的数据长度(iTotalLength)是否满足处
理条件,选择性地进行处理。 当 iTotalLength 小于当前期望的长度时可以忽略本次
事 件 ; 当 iTotalLength 大 于 或 等 于 当 前 期 望 的 长 度 时 , 循 环 调 用 组 件 的
Fetch(dwConnID, pData, iDataLength) 方法把需要的数据拉取出来,直到剩余的数
据长度小于当前期望的长度。
PULL 模型适用于完全清楚应用层协议,并且应用层协议可以根据当前数据包得知下一
个数据包长度的场景。典型的场景如 Head + Body, Head 长度固定,第一个数据包为 Head,
通过 Head 得知 Body 的长度,接收完 Body 之后下一个数据包一定为 Head。 - PACK 模型组件触发监听器对象的 OnReceive(pSender, dwConnID, pData, iLength)
事件时,会保证 pData 是一个完整的数据包。 PACK 模型组件会对应用程序发送的
每个数据包自动加上 4 字节(32 位) 的包头, 组件接收到数据时根据包头信息自
动分包, 每个完整数据包通过 OnReceive 事件发送给应用程序。