1.判断收到的数据包,能否读出一个数据包(读取”/r/n”命令包结束符)。
2.如果收到数据包大于了接受buff的最大长度,就分配2倍的内存空间。并修正指针指向的位置。然后投递recv请求。
3.如果大于最大接受数据,那么关闭session,释放socket,如果接受的数据大于了pkg_size,那么久修正指针指向的内容。
4.如果收到buffer = 0的话,释放long_pkg,投递recv请求
1.获取数据头
static int read_pkg_tail(unsigned char* pkg_data, int recv, int* pkg_size){
if (recv < 2){// 不可能存放\r\n
return -1;
}
int i = 0;
*pkg_size = 0;
while (i < recv - 1) {
if (pkg_data[i] == '\r' && pkg_data[i + 1] == '\n') {
*pkg_size = (i + 2);
return 0;
}
i++;
}
return -1;
}
2.分包协议的实现
static void recv_json(struct io_package* io_data, struct session* s, DWORD dwTrans){
// 做这个包的完整读取
io_data->recved += dwTrans; // 收到了这么多的数据;
while (io_data->recved > 0)
{
int pkg_size = 0;
unsigned char* pkg_data = (io_data->long_pkg != NULL) ? io_data->long_pkg : io_data->pkg;
if (read_pkg_tail(pkg_data, io_data->recved, &pkg_size) != 0){// 没有读到\r\n
if (io_data->recved >= (((1 << 16) - 1))){ // 超过了数据包,close session
close_session(s);
free(io_data);
break;
}
if (io_data->recved >= io_data->max_pkg_len)
{
// pkg,放不下了
int alloc_len = io_data->recved * 2;
alloc_len = (alloc_len > ((1 << 16) - 1)) ? ((1 << 16) - 1) : alloc_len;
if (io_data->long_pkg == NULL) { // 小缓存存不下这个命令
io_data->long_pkg = malloc(alloc_len);
memcpy(io_data->long_pkg, io_data->pkg, io_data->recved);
}
else {
io_data->long_pkg = realloc(io_data->long_pkg, alloc_len);
}
io_data->max_pkg_len = alloc_len;
}
DWORD dwRecv = 0;
DWORD dwFlags = 0;
unsigned char* buf = (io_data->long_pkg != NULL) ? io_data->long_pkg : io_data->pkg;
io_data->wsabuffer.buf = buf + io_data->recved;
io_data->wsabuffer.len = io_data->max_pkg_len - io_data->recved;
int ret = WSARecv(s->c_sock, &(io_data->wsabuffer),
1, &dwRecv, &dwFlags,
&(io_data->overlapped), NULL);
break;
}
// 读到了这个数据,找到了这样的命令, io_data->pkg,开始, pkg_size
on_server_recv_line(s, pkg_data, pkg_size);
if (io_data->recved > pkg_size) {
memmove(pkg_data, pkg_data + pkg_size, io_data->recved - pkg_size);
}
io_data->recved -= pkg_size;
if (io_data->recved == 0) { // IOCP的请求
DWORD dwRecv = 0;
DWORD dwFlags = 0;
if (io_data->long_pkg != NULL) {
free(io_data->long_pkg);
io_data->long_pkg = NULL;
}
io_data->max_pkg_len = MAX_RECV_SIZE;
io_data->wsabuffer.buf = io_data->pkg + io_data->recved;
io_data->wsabuffer.len = io_data->max_pkg_len - io_data->recved;
int ret = WSARecv(s->c_sock, &(io_data->wsabuffer),
1, &dwRecv, &dwFlags,
&(io_data->overlapped), NULL);
break;
}
}
}
转载请说明出处:http://blog.csdn.net/u013158916/article/details/54297797