HPSocket 三种模型PACK,PUSH,PULL
更多信息请参看HP-Socket网络通信框架开发指南v5.2-20180201(https://download.csdn.net/download/cair2/10636514)由于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;
}
}
所以综上所述模型:
PUSH:接受到数据之后就出发OnReceive,由开发人员自己实现上述拆包和计算缓冲区的管理逻辑。
PULL:接受到数据之后就出发OnReceive,但是开发人员只需要维护数据包的长度,数据缓冲区管理HP内部帮你做了,当足够一个包的时候,Fetch获取一个完整的数据包就OK了。
PACK:接受到数据之后就出发OnReceive,开发人员不必管理上述的过程,OnReceive的数据就是一个完整的包。 说TCP【粘包】的人,一定对TCP存在很深的误解。
TCP是【字节流】,不是【包】,UDP才是【包】。
如果你用TCP一次性SEND了100字节,那么你可以调用RECV循环100次,每次接收1字节。
如果你用UDP一次性SENDTO了100字节,那么你【能且只能】用RECVFROM接收1次,一次性100字节。 TCP【粘包】是个伪概念,当然也说明了一些编码中存在的问题,在源源不断的数据流中我们得再次分出事先已经分好的数据块。
UDP完全是不可靠的,而且一次性send不能太多,否则报错,最好不大于512字节。UDP发过去的数据包可能不完整、可能顺序错了,都很正常。想使用UDP建议使用封装好的可靠UDP,性能会比TCP高一些
页:
[1]