c# httpclient post force single packet
Asked Answered
A

1

11

Using Microsoft Message Analyzer, I can see that post data using the HttpClient is being sent in two tcp packets. One for the header, then one for the post data. This data could easily fit into one packet, however it is being split into two. I have explicitly turned on nagling and expect 100 continue off using the ServicePointManager, though, it doesn't seem to help.

        ServicePointManager.Expect100Continue = false;
        ServicePointManager.UseNagleAlgorithm = true;

Microsoft Message Analyzer 5023 (.Net) shows 2 packets are sent to destination, 8170 (Postman) shows 1 packet being sent. Tests were done with the same payload.

Below is some sample code used to generate the request in .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;
    }

Is there a way to force the payload into a single packet?

Using .Net Framework 4.7

related question here

Artemas answered 9/4, 2018 at 7:35 Comment(7)
I'm voting to close this question as off-topic because you know its a duplicate of another question - despite there being no answer that doesnt make this betterSubmariner
Nagle can only reduce the number of packets being sent, so turning it off won't help.Aesthesia
And why exactly it's a problem for you?Marder
thank you @Submariner - but I don't have enough reputation to post a comment on the main thread on that post asking if OP ever found a solution......Artemas
@Aesthesia - I have tested with Expect 100 Continue off and Nagle on and still the same issue.Artemas
@Marder - We are trying to heavily optimize http requests on very busy servers.Artemas
@CalvinPietersen Nagle doesn't fix your problem, but the only thing it can ever do is combine packets. It only does so when it hasn't received an ACK on a previously sent packet.Aesthesia
A
2

So after looking at the dotnet core source code (can only assume the same in other .net versions), I can see in the WinHttpHandler that the Request Header and Request Body are sent at different points.

The request header is sent with Interop.WinHttp.WinHttpSendRequest. Then the request body with Interop.WinHttp.WinHttpWriteData which according to the WinHttp docs, will "Wait until WinHttpSendRequest has completed before calling this function".

I think this issue could be solved, if the request body was sent with the WinHttpSendRequest, which currently sets the body as IntPtr.Zero.

Request Header here

Request Body here

Artemas answered 12/4, 2018 at 5:2 Comment(1)
Interesting findings Calvin!Baber

© 2022 - 2024 — McMap. All rights reserved.