IOCP JSON 协议分包

  • 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值