Я реализую приложение TCP/IP-сервера, которое использует epoll в режиме с краем и выполняет неблокирующие операции сокета. Клиенты используют простые операции блокировки без epoll.C socket atom non-blocking read
Я не вижу, как «атомные чтения» могут быть реализованы на стороне сервера. Чтобы объяснить, что я имею в виду «атомное считывание», см. Этот пример с простыми операциями блокировки:
- И клиент, и сервер используют буферы 64 КБ. (На уровне приложений. Они не меняют буферы сокета уровня ядра.)
- Клиент записывает данные 12K с одной записью.
- Сервер читает его. В этом случае он всегда читает все 12K, когда буферы одинаковы. Поэтому он не может читать только половину. Это то, что я называю «атомарным».
Но в случае Epoll + неблокирующие операции это может произойти:
- И клиент и сервер используют 64K буферов. (На уровне приложений. Они не меняют буферы сокета уровня ядра.)
- Клиент записывает данные 12K с одной записью.
- 6K поступает на сервер
- Epoll указывает приложению, что данные прибывшего в сокет
- приложение считывает 6К в буфер, используя нелипкая операцию.
- При повторном чтении он возвращает EAGAIN/EWOULDBLOCK.
В этом случае чтение не является «атомарным». Не гарантируется, что, когда данные были записаны с помощью одной операции записи, чтение будет возвращать целое в одном фрагменте.
Можно ли узнать, когда данные являются частичными? Я знаю, что одно решение заключается в том, чтобы всегда добавлять размер данных в начало, иначе можно было бы всегда закрывать и повторно открывать соединение, но я не хочу этого делать: потому что я думаю, что ядро должно знать, что не полный «пакет» (как называется эта единица, называемая BTW?), поскольку она обеспечивает атомарность для операций блокировки.
Большое спасибо!
Обычно нужно писать все операции ввода/вывода в * петли * и поддерживать свои собственные буферы. –
Если ваш вызов 'read' в сокете не возвратил' 0', вы можете ожидать, что там будет больше данных, которые вы можете захватить в цикле событий. – jacob
В двоичной передаче обычно используется разделитель, такой как начало передачи и конец передачи. В текстовых передачах проверка синтаксиса является вашим другом. Если вы передаете строки json, вы можете проанализировать строку json, чтобы определить, завершено ли это или нет. – alvits