Как предотвратить фрагментацию пакетов для HttpWebRequest

У меня есть проблема с помощью HttpWebRequest против демона HTTP на встроенном устройстве. Проблема, кажется, что существует действительно задержка между http заголовками, записанными в поток сокета и http полезной нагрузкой (POST), что сокет выпускает то, что находится в буфере сокета к серверу. Это приводит к Запросу HTTP, разделяемому по двум пакетам (фрагментация).

Это совершенно допустимо, конечно, однако сервер, другой конец не справляется с ним, если пакеты разделяются на больше, чем приблизительно 1,8 мс. Таким образом, я задаюсь вопросом, существуют ли какие-либо реалистические способы управлять этим (на клиенте).

Кажется, нет никаких свойств на HttpWebRequest, которые дают этот уровень управления сокетом, используемым для отправления, и, можно казаться, не получает доступ к самому сокету (т.е. через отражение), потому что это только создано во время отправления и выпущено впоследствии (как часть исходящего http материала организации пула подключений). Свойство BufferWriteStream просто буферизует содержимое тела в webrequest (таким образом, это все еще доступно для перенаправлений и т.д....), и, кажется, не влияет на способ, которым полный запрос записан в сокет.

Таким образом, что сделать?

(Я действительно стараюсь не иметь необходимость переписать клиент HTTP от сокета),

Одна опция могла бы состоять в том, чтобы записать некоторый прокси, который HttpWebRequest отправляет в (возможно, через ServicePoint), и в той реализации буферизуют весь запрос TCP. Но это походит на большую тяжелую работу.

Это также хорошо работает, когда я выполняю Fidder (по той же причине), но это не действительно опция в нашей продуктивной среде...

[PS: Я знаю, что это - определенно интервал между фрагментированными пакетами, это - проблема, потому что я поднял тест уровня сокета, где я явно управлял фрагментацией с помощью сокета NoDelay]

8
задан piers7 5 February 2010 в 07:11
поделиться

2 ответа

Является ли встроенный сервер сервером HTTP/1.1? Если да, попробуйте установить значение Expect100Continue=false в веб-запросе перед вызовом GetRequestStream(). Это гарантирует, что HTTP-стек не ожидает ответа заголовка "HTTP/1.1 100 continue" от сервера перед отправкой тела сущности. Таким образом, даже если пакеты все равно будут разделены между заголовком и телом, межпакетный разрыв будет меньше.

1
ответ дан 6 December 2019 в 00:06
поделиться

Окно является одним из объектов DOM верхнего уровня (1) (2) . Demo - нестандартное свойство, реализуемое Android.

-121--5044441-

Трие кажется очень хорошей идеей для ваших ограничений.

Альтернатива «мышления вне рамки»:

Если вы можете позволить себе некоторую вероятность ответа «present» на последовательность

EDIT: если вы можете позволить себе ложные положительные результаты, используйте фильтр Блума , как предложено WizardOfOdds в комментариях.

Для k = 1 фильтр Блума подобен хэш-таблице без ключей: каждое «ведро» - это просто логическое значение, указывающее, присутствовал ли хотя бы один вход с тем же хэшем. Если допустимо 1% ложных срабатываний, то размер хэш-таблицы может быть равен примерно 100 * 20 миллионам бит или примерно 200 МиБ. Для 1 из 1000 ложных срабатываний, 2GiB.

Использование нескольких хеш-функций вместо одной может улучшить ложноположительную скорость для одного и того же количества битов.

-121--1395521-

Что казалось исправленным, так это отключение Nagling на ServicePoint, связанной с этим URI, и отправка запроса как HTTP 1,0 (ни один из них сам не исправляет его):

var servicePoint = ServicePointManager.FindServicePoint(uri.Uri);
servicePoint.UseNagleAlgorithm = false;

Однако это все еще, кажется, исправило его, только заставив запрос выходить быстрее, а не заставляя заголовки и полезную нагрузку записываться как один пакет. Так что он, предположительно, может выйти из строя на загруженной машине/связи с высокой задержкой и т.д.

Интересно, как трудно будет написать дефрагментацию прокси...

1
ответ дан 6 December 2019 в 00:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: