Если ваше приложение является сервером, способным обрабатывать несколько клиентов одновременно, а неблокирующие сокеты используются для обработки нескольких клиентов в одном потоке, у вас нет другого выбора, кроме как когда-либо выдавать только один вызов recv (), когда сокет готов кread.
Причина в том, что если вы продолжаете вызывать recv () в цикле, а клиент отправляет большой объем данных, то может случиться, что ваш цикл recv () может заблокировать поток на долгое времяделать что-то еще.Например, recv () считывает некоторое количество данных из сокета, определяет, что теперь в буфере есть полное сообщение, и перенаправляет это сообщение в обратный вызов.Обратный вызов как-то обрабатывает сообщение и возвращает.Если вы вызываете recv () еще раз, может появиться больше сообщений, поступивших во время обработки обратного вызова предыдущего сообщения.Это приводит к занятому циклу recv () на одном сокете, не позволяющему потоку обрабатывать любые другие ожидающие события.
Эта проблема усугубляется, если буфер чтения сокета в вашем приложении меньше, чем приемный буфер сокета ядра.Другими словами, все содержимое буфера приема ядра не может быть прочитано за один вызов recv ().Неподтвержденное свидетельство - то, что я столкнулся с этой проблемой в занятой производственной системе, когда был буфер пространства пользователя в 16 КБ для буфера приема сокета ядра 2 МБ.Клиент, отправляющий много сообщений подряд, блокирует поток в этом цикле recv () на несколько минут, поскольку при обработке только что прочитанных сообщений будет поступать больше сообщений, что приведет к прерыванию службы.
В таком событииДля управляемых архитектур лучше всего иметь буфер чтения пользовательского пространства, равный размеру приемного буфера сокета ядра (или максимальному размеру сообщения, в зависимости от того, что больше), чтобы все данные, доступные в буфере ядра, можно было прочитать в одномвызов recv ().Это работает, выполняя один вызов recv (), обрабатывая все полные сообщения в буфере чтения пользовательского пространства и затем возвращая управление в цикл обработки событий.Таким образом, соединения с большим количеством поступающих данных не блокируют поток от обработки других событий и соединений, скорее это циклическая обработка всех соединений с доступными входящими данными.