我有一个简单的tcp / ip服务器用c ++在linux上编写。 我使用asynchronous套接字和epoll。 是否有可能find有多less字节可供阅读,当我得到EPOLLIN事件?
从man 7 tcp
:
int value; error = ioctl(sock, FIONREAD, &value);
或者是SIOCINQ
,这是FIONREAD
的同义词。
无论如何,我建议只是在循环中使用非阻塞模式的recv
,直到它返回EWOULDBLOCK
。
更新:
从您的评论下面我认为这不是适合您的问题的解决方案。
试想一下,你的头是8个字节,你只收到4; 那么你的poll/select
会返回EPOLLIN
,你会检查FIONREAD
,看看头还没有完成,还有更多的字节。 但是这些字节永远不会到达,因此每次调用poll/select
调用时都会继续获取EPOLLIN
,并且您有一个无操作的忙循环。 也就是说, poll/select
是电平触发的 。 不是边缘触发功能也可以解决你的问题。
最后你做好一点工作,每个连接添加一个缓冲区,然后排队这些字节,直到有足够的空间。 这并不像看起来那么困难,而且效果也好很多。 例如,类似的东西:
struct ConnectionData { int sck; std::vector<uint8_t> buffer; size_t offset, pending; }; void OnPollIn(ConnectionData *d) { int res = recv(d->sck, d->buffer.data() + offset, d->pending); if (res < 0) handle_error(); d->offset += res; d->pending -= res; if (d->pending == 0) DoSomethingUseful(d); }
而且,只要你想获得一些字节数:
void PrepareToRecv(ConnectionData *d, size_t size) { d->buffer.resize(size); d->offset = 0; d->pending = size; }