IOCP 二进制协议 分包

来源:互联网 发布:有肉的耽美网络剧 编辑:程序博客网 时间:2024/04/27 20:53

一、IOCP 二进制协议分包的思路

  1. 解析数据头,获取协议包体的大小,判断是否收到一个完整的数据头,
    如果不是,继续投递recv请求,直到收到一个数据头

  2. 异常的数据包,关闭session (pkg_size > MAX_PKG_SIZE)

  3. 全部数据收到,进行处理.

    1 判断long_pkg是否存在,如果存在,就要释放
    2.如果收到数据 > pkg_size,io_data->pkg指向正确的位置
    3.如果收到数据 = 0,那么就继续投递recv请求

  4. 没有收到全部数据
    1.pkg_size > MAX_RECV_SIZE,那么就申请内存空间!存放pkg,否则继续收数据
    2.继续投递请求

二、代码实现

1.获取收到的数据的长度
static int read_header(unsigned char* header, int len, int* pkg_size){    if (len < 2){        return -1;    }    int size = (header[0]) | (header[1] << 8);    *pkg_size = size;    return 0;}
2.接受数据的结构
struct io_package {    WSAOVERLAPPED overlapped;    WSABUF wsabuffer;    int opt; // 标记一下我们当前的请求的类型;    int accpet_sock;    int recved;    unsigned char* long_pkg;    unsigned char pkg[MAX_RECV_SIZE];};
3.对收到数据进行分包
case IOCP_RECV: { // 完成端口意味着数据已经读好io_data->recved += dwTrans;while (io_data->recved > 0){    int pkg_size = 0;    if (read_header(io_data->pkg, io_data->recved, &pkg_size) < 0){// 不够读取包头size大小        io_data->wsabuffer.buf = io_data->pkg + io_data->recved;        io_data->wsabuffer.len = MAX_RECV_SIZE - io_data->recved;        // 当读的请求完成后,必须要再加一个读的请求;        DWORD dwRecv = 0;        DWORD dwFlags = 0;        int ret = WSARecv(s->c_sock, &(io_data->wsabuffer),1,&dwRecv,&dwFlags,&(io_data->overlapped),NULL);        break;    }    if (pkg_size > MAX_PKG_SIZE){        close_session(s);        free(io_data);    }    if (io_data->recved >= pkg_size){ // 全部收到,进行处理        char* pkg = (io_data->long_pkg == NULL) ? io_data->pkg : io_data->long_pkg;        on_server_recv(s, pkg + 2, pkg_size - 2);        if (io_data->long_pkg != NULL){            free(io_data->long_pkg);            io_data->long_pkg = NULL;        }        if (io_data->recved > pkg_size){            memmove(io_data->pkg, io_data->pkg + pkg_size, pkg_size - io_data->recved);        }        io_data->recved -= pkg_size;        if (io_data->recved == 0){            io_data->wsabuffer.buf = io_data->pkg + io_data->recved;            io_data->wsabuffer.len = MAX_RECV_SIZE - io_data->recved;            // 当读的请求完成后,你必须要再加一个读的请求;            DWORD dwRecv = 0;            DWORD dwFlags = 0;            int ret = WSARecv(s->c_sock, &(io_data->wsabuffer),                1, &dwRecv, &dwFlags,                &(io_data->overlapped), NULL);            break;        }    }    else{//没有读完        if (pkg_size > MAX_RECV_SIZE){            if (io_data->long_pkg == NULL) {                io_data->long_pkg = malloc(pkg_size);                memcpy(io_data->long_pkg, io_data->pkg, io_data->recved);            }            io_data->wsabuffer.buf = io_data->long_pkg + io_data->recved;            io_data->wsabuffer.len = pkg_size - io_data->recved;        }        else{            io_data->wsabuffer.buf = io_data->pkg + io_data->recved;            io_data->wsabuffer.len = pkg_size - io_data->recved;        }        // 当读的请求完成后,你必须要再加一个读的请求;        DWORD dwRecv = 0;        DWORD dwFlags = 0;        int ret = WSARecv(s->c_sock, &(io_data->wsabuffer),            1, &dwRecv, &dwFlags,            &(io_data->overlapped), NULL);        break;    }    }}

转载请说明出处:http://blog.csdn.net/u013158916/article/details/54271180

0 0
原创粉丝点击