Используя Microsoft Message Analyzer, я вижу, что данные публикации с использованием HttpClient отправляются двумя пакетами tcp. Один для заголовка, затем один для данных публикации. Эти данные могут легко поместиться в один пакет, однако он разбивается на два. Я явно включил ворчание и ожидаю, что 100 продолжат отключение с помощью ServicePointManager, хотя, похоже, это не помогает.
ServicePointManager.Expect100Continue = false;
ServicePointManager.UseNagleAlgorithm = true;
5023 (.Net) показывает, что 2 пакета отправлены по назначению, 8170 (Почтальон) показывает, что отправляется 1 пакет. Тесты проводились с той же полезной нагрузкой.
Ниже приведен пример кода, используемого для генерации запроса в .net.
public void TestRequest()
{
var uri = new Uri("http://www.webscantest.com/");
ServicePointManager.Expect100Continue = false;
ServicePointManager.UseNagleAlgorithm = true;
var p = ServicePointManager.FindServicePoint(uri);
p.Expect100Continue = false;
p.UseNagleAlgorithm = true;
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Connection", "close");
var values = new Dictionary<string, string>
{
{ "thing1", "hello" },
{ "thing2", "world" }
};
var content = new FormUrlEncodedContent(values);
var response = client.PostAsync("http://www.webscantest.com/", content, CancellationToken.None).Result;
}
Есть ли способ объединить полезную нагрузку в один пакет?
Использование .Net Framework 4.7
Nagle может только уменьшать количество отправляемых пакетов, поэтому его отключение не поможет.
А почему именно для вас это проблема?
спасибо @BugFinder, но у меня недостаточно репутации, чтобы опубликовать комментарий в основной теме этого сообщения, спрашивая, нашел ли OP когда-нибудь решение ...
@ C.Evenhuis - Я тестировал с выключенным Expect 100 Continue и включенным Nagle, и проблема все еще та же.
@Evk - Мы пытаемся сильно оптимизировать HTTP-запросы на очень загруженных серверах.
@CalvinPietersen Nagle не решает вашу проблему, но единственное, что он может сделать, - это объединить пакеты. Это происходит только в том случае, если он не получил ACK на ранее отправленный пакет.





Поэтому, посмотрев на исходный код ядра dotnet (могу только предположить то же самое в других версиях .net), я вижу в WinHttpHandler, что Заголовок запроса и Тело запроса отправляются в разных точках.
Заголовок запроса отправляется с Interop.WinHttp.WinHttpSendRequest. Затем тело запроса с Interop.WinHttp.WinHttpWriteData, которое, согласно документам WinHttp, будет «Дождитесь завершения WinHttpSendRequest перед вызовом этой функции».
Я думаю, что эту проблему можно было бы решить, если бы тело запроса было отправлено с помощью WinHttpSendRequest, который в настоящее время устанавливает тело как IntPtr.Zero.
Интересные находки Кальвина!
Я голосую за то, чтобы закрыть этот вопрос как не по теме, потому что вы знаете, что это дубликат другого вопроса - несмотря на то, что нет ответа, который не улучшил бы его.