Epoll epollin读取数据

时间:2012-03-20 05:13:07

标签: c linux epoll

在我接受设置为侦听EPOLLIN事件的连接套接字并且收到EPOLLIN事件后,使用epoll,我是否必须读取所有数据(直到0 )在我epoll_ctlEPOLLOUT之前?

示例:我有一个使用epoll的HTTP服务器,我只想阅读(EPOLLIN recv)HTTP标头,直到\r\n\r\n。我是否可以安全地忽略消息的其余部分而不读取它并切换到输出(EPOLLOUTsend)?

1 个答案:

答案 0 :(得分:1)

简短回答是肯定的,这是安全的。一些事情。

“读取所有数据直到0”的替代方案实际上无论如何都不会起作用。浏览器客户端不会关闭/关闭其套接字的结尾,直到它消耗掉服务器的响应。因此,您将停止等待recv返回0,因为远程客户端仍在等待您的响应。

假设您没有使用边缘触发模式,您应该没问题,不必担心错过任何通知。您可以只使用带有EPOLLIN通知和recv()的标头,然后使用epoll_ctl套接字来接收EPOLLOUT通知。当你完成发送响应时,安全的做法是切换回监听EPOLLIN通知(可能还有EPOLLHUP和EPOLLRDHUP)来消耗请求中的任何额外数据,直到客户端关闭他的套接字(在这种情况下,recv将返回0) )。

也可以使用边缘触发模式。只需确保使用非阻塞套接字并在切换到响应模式时尝试无阻塞发送,即使您没有获得初始EPOLLOUT也是如此。切换回读取模式时,如果丢失了早期的EPOLLIN,请执行非阻塞recv。

如果哑客户端尝试发送的不仅仅是标头(如一长串POST数据字节),那么客户端可能不会尝试在完成发送之后重新获取响应。因此,您陷入虚拟僵局。服务器和客户端都无法将额外的字节写入其套接字,因为任何一方都没有读取。简单的解决方案是确保在发送响应之前使用整个请求(标题和“Content-Length”字节)。