数据分包

1数据分包

在TCP收数据的时候可能会有一个很大的包,这时候很有可能一次就收不完,

或者说一次收到多个数据包,

二进制分包常用的就是size+body的方式;

为了避免服务器被恶意的攻击, 一般会规定一个包的大小上线,

如果超过了,立刻关闭该链接. 比如两个字节表示长度就是64kb


第一次就是提交一个请求




2数据分包实现思路

1先设置一块内存,并设置大小是可以读取的内存数据,如果完成了这个请求

就会返回实际读到的大小,处理完后继续投递请求;


2 发送投递请求的默认大小为8192(1024*8)  也可以是4k就是命令的大小

如果要收收的数据包 小与 8k,可能有两种情况

1 收到的数据大小 大于等于 一个包的数据大小(就是说你可能收到了两个数据包)

处理完整的包,将剩下的不足一个包的数据移动到下一次投递,跳过那部分内容即可。

这就是粘包

2收到的数据只有一个字节,不足header长度,保留继续 投递recv.

3 如果要收的数据>8k  那么肯定第一次收不完,所以,要重新分配一个数据包

大小的内存来保存这个数据包,投递请求的时候,根据这个大小来投递,不多收。

因为已经知道这个大的数据包有多大,收完后才重新投递。




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
首先设置这个包的最大上限  如果超过了这个上限 就认定是恶意 数据包  直接断开连接
 
//左移16位  就是两个字节最大 然后-1   
//0000000000000001   1000000000000000 -1 1111111111111111
//转换成16进制0xFFFF 十进制  61440+3840+240+15  65535
#define MAX_PAG_SIZE ((1<<16) - 1)  //包的上限制
 
 
#define MAX_RECV_SIZE 2048          //一个包的大小
 
struct  io_package {
     WSAOVERLAPPED overlapped;              //重叠结构用于IOCP
     WSABUF wsabuffer;                      //收数据的缓冲区
     int  opt;  // 标记一下我们当前的请求的类型;  //事件类型 
     int  accpet_sock;
 
     int  recv;          //当前io_data 缓冲了多少数据
     unsigned  char * long_pkg;   //处理大的数据包的情况 > MAX_RECV_SIZE
     char  pkg[MAX_RECV_SIZE];  //投递百分之90游戏命令的大小
};



3现在我规定 前面两个字节是大小 如果只收到一个字节就要继续recv

1
2
3
4
5
6
7
8
9
10
io_data->recv += dwTrans;  //当前读取到数据的总大小
if (io_data->recv < 1)   //收到的数据小于一个字节那就退出  因为包长都获取不到
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值