检查套接字缓冲区而不消耗它

时间:2016-08-31 00:04:54

标签: c linux sockets

我有以下示例使用libevent,epoll库:

void read_cb(struct bufferevent *bev, void *arg)
{
    evutil_socket_t fd = bufferevent_getfd(bev);
    struct evbuffer *input = bufferevent_get_input(bev);

    while( 1 ) {
        int datalen = 0 ;
        char buflen[5]={0},record[1024]={0} ;

        size_t len1 = evbuffer_get_length(input);
        if(len1 < 4)
            return ;
        evbuffer_copyout(input, buflen, 4) ;

        try{
            std::string s(buflen) ;
            datalen = stoi(s) ;
        }catch(std::exception const &e){
            std::cout << "error:" << e.what() << std::endl ;
            return ;
        }

        size_t len2 = evbuffer_get_length(input);
        if(len2 < (4+datalen) )
            return ;
        evbuffer_drain(input, 4);
        evbuffer_remove(input,record,datalen) ;
        record[datalen] = 0x00 ;
        console->info("fd ({}) receive ({})",fd,record) ;
        DoOrder(fd,record) ;
    } //while

    return ;
}

客户端发送流如“0010abcdefghij”,前4个字节描述数据部分有10个字节,所以我的源检查缓冲区中是否有4个字节?如果是这样 , 复制4个字节(但不消耗它),检查正文的长度,然后再次检查 如果所有标题(4个字节)和正文(在我的情况下,它是“abcdefghij”)都在缓冲区中,如果是这样,则将标题和正文(在我的情况下,14个字节)排除在缓冲区之外。

我喜欢自己做(不使用libevent),我知道

int bytesAv = 0;
ioctl(m_Socket,FIONREAD,&bytesAv); //m_Socket is the socket client's fd 

可以检查缓冲区中可用的字节数(比如我的示例中的bufferevent_get_input),我不知道如何实现evbuffer_copyout, 这意味着,我不仅要检查socket fd中可用的字节数 缓冲区,我也喜欢从缓冲区中复制几个字节来检查它的内容,调用什么函数来做这个工作?!

编辑:

recv with flags MSG_DONTWAIT | MSG_PEEK on TCP socket

描述MSG_PEEK和MSG_DONTWAIT仍然进行套接字阻塞,这不适合我,因为在我的情况下,我只是想非阻塞地检查缓冲区内容,阻塞将无法为我做正确的工作。

Edit2:

使用ioctl(m_Socket,FIONREAD,&amp; bytesAv);和recv(... MSG_PEEK)在一起, 我不应该担心阻塞,因为我总是可以使用FIONREAD来检查 首先,然后使用MSG_PEEK进行recv根本不会出现阻塞问题。

0 个答案:

没有答案