我有以下示例使用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根本不会出现阻塞问题。