Я работаю над сервером UDP, созданным с повышением:: asio и я запустились от учебной настройки до моих потребностей. Когда я звоню socket.receive_from(boost::asio::buffer(buf), remote, 0, error);
это заполняет мой буфер данными из пакета, но, если мое понимание корректно, оно отбрасывает любые данные, которые не поместятся в буфер. Последующие вызовы к receive_from получат следующую доступную датаграмму, таким образом, это будет смотреть на меня, любят существует некоторая потеря данных даже без уведомления. Я понимаю это неправильный путь?
Я пытался читать много раз повышение:: документация asio, но мне не удалось найти подсказки относительно того, как я, как предполагается, делаю это правильный путь. То, что я хотел бы сделать, читает определенное количество данных так, чтобы я мог обработать их; если чтение всей датаграммы является единственным путем, я могу управлять этим, но затем как я, несомненно, не смогу потерять данные, которые я получаю? Какой размер буфера я должен использовать, чтобы быть уверенным? Там какой-либо путь состоит в том, чтобы сказать, что мой буфер является слишком маленьким, и я теряю информацию?
Я должен предположить, что могу получать огромные датаграммы дизайном.
Это не специфично для boost; это просто то, как работают сокеты дейтаграмм. Вы должны указать размер буфера, и если пакет не помещается в буфер, то он будет усечен, и нет способа восстановить потерянную информацию.
Например, протокол SNMP определяет, что:
Реализация этого протокола не должна принимать сообщения, длина которых превышает 484 октета. Однако рекомендуется, чтобы реализация поддерживала более длинные дейтаграммы, когда это возможно.
Короче говоря: при разработке протокола связи вы должны учитывать, что дейтаграммы могут быть потеряны, или они могут быть усечены сверх определенного размера.
Используйте getsockopt
с параметром SO_NREAD.
Из справочной страницы Mac OS X:
SO_NREAD возвращает объем данных во входном буфере, который доступен для приема. Для сокетов, ориентированных на грамматику данных, SO_NREAD возвращает размер первого пакета - это отличается от команды FIONREAD ioctl (), которая возвращает общий объем доступных данных.