在epoll中,在我接受了一个设置为侦听EPOLLIN事件的连接套接字之后,我得到了一个EPOLLIN事件,我是否必须在epoll_ctl to only EPOLLOUT之前读取所有的数据(直到0
示例:我有一个使用epoll的超文本传输协议服务器,我只想读取(使用recv的EPOLLIN)HTTP头,直到\r\n\r\n为止。我可以安全地忽略消息的其余部分而不阅读它,并切换到输出(使用send的EPOLLOUT)吗?
发布于 2012-03-20 15:19:42
简短的回答是肯定的,它是安全的。几件事。
“读取所有数据直到0”的替代方案实际上无论如何都不会起作用。浏览器客户端不会关闭/关闭套接字的一端,直到它使用了从服务器返回的响应。因此,您将等待recv返回0,因为远程客户端仍在等待您的响应。
假设你没有使用边缘触发模式,你应该可以不用担心遗漏任何通知。您可以只使用带有EPOLLIN通知和recv()的头,然后epoll_ctl套接字以仅接收EPOLLOUT通知。发送完响应后,安全的做法是切换回侦听EPOLLIN通知(可能还有EPOLLHUP和EPOLLRDHUP),以使用请求中的任何额外数据,直到客户端关闭其套接字(在这种情况下,recv将返回0)。
也可以使用边缘触发模式。只需确保使用非阻塞套接字,并在切换到响应模式时尝试非阻塞发送,即使您没有得到初始EPOLLOUT。当切换回读取模式时,执行非阻塞recv,以防丢失早期的EPOLLIN。
在某种程度上,如果哑巴客户端尝试发送的不仅仅是报头(比如一组很长的POST数据字节),那么在完成发送之前,客户端可能不会尝试接收响应。如此一来,你就陷入了一个虚拟的死锁。服务器和客户端都不能向套接字中写入额外的字节,因为两端都没有读取。简单的解决方案是确保在发送响应之前使用整个请求(报头和"Content-Length“字节)。
https://stackoverflow.com/questions/9781659
复制相似问题