Короткий ответ - да, это безопасно.Несколько вещей.
Альтернатива «прочитать все данные до 0» фактически не сработает.Клиент браузера не будет закрывать / закрывать свой конец сокета, пока не получит ответ от сервера.Таким образом, вы ожидаете, что recv вернет 0, потому что удаленный клиент все еще ждет вашего ответа.
Предполагая, что вы не используете режим с триггерным фронтом, у вас должно быть все в порядке, не беспокоясь о том, что пропуститеуведомления.Вы можете использовать только заголовок с уведомлениями EPOLLIN и recv (), а затем epoll_ctl сокет, чтобы просто получать уведомления EPOLLOUT.Когда вы закончите отправку ответа, безопаснее всего вернуться к прослушиванию уведомлений EPOLLIN (и, возможно, EPOLLHUP и EPOLLRDHUP), чтобы использовать любые дополнительные данные в запросе, пока клиент не закроет свой сокет (в этом случае recv вернет 0).
Можно также использовать режим запуска по краю.Просто убедитесь, что используете неблокирующие сокеты и попробуйте неблокирующую отправку при переключении в режим ответа, даже если вы не получили начальный EPOLLOUT.При переключении обратно в режим чтения сделайте неблокирующее recv на случай, если вы потеряли более ранний EPOLLIN.
В некоторой степени возможно, если тупой клиент пытается отправить больше, чем просто заголовок (например, длинный набор POST).байты данных), клиент может не пытаться получить ответ до тех пор, пока он не закончит отправку.Таким образом, вы попадаете в виртуальный тупик.И сервер, и клиент не могут записать дополнительные байты в свои сокеты, потому что ни одна из сторон не читает.Простое решение - убедиться, что вы используете весь запрос (заголовок и байты «Content-Length») перед отправкой ответа.