C# HTTPClient 不会重用 SSL/TLS1.2 会话,并且会对每个请求进行握手

问题描述 投票:0回答:1

就像网上到处说的那样,创建了一个私有静态只读 HTTPClient,它在整个应用程序中被重用,但是每个请求都会发生 SSL/TLS1.2 握手,因此每个请求需要近 6 秒才能获得响应我做。这是我的代码,我试图将字节数组分块发布到服务器。我正在使用 dotnet6。

    private static readonly HttpClient client = new HttpClient(new HttpClientHandler
    {
        Credentials = new NetworkCredential("admin", "private"),
        ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => 
        true,
        CheckCertificateRevocationList = true,
        PreAuthenticate = true,
        //UseCookies = true,
        //CookieContainer = cookieContainer,

    });


    

    private async void button1_Click(object sender, EventArgs e)
    {
        
        
        //System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12| SecurityProtocolType.Tls11 | SecurityProtocolType.Tls| SecurityProtocolType.Tls13;

        try
        {
            string http = "https://";
            string fwupdate = "/fwup_install";
            string fwreset = "/fwup_reset";
            string ip = txt_ip.Text;
            byte[] Data = null;
            byte[] array1 = null;
            string filePath = "D:\\fw\\iol_mix_mp_https.fwu";
            Data = File.ReadAllBytes(TxT_SelectedFwuFile.Text);
            var url = http + ip + fwupdate;   

            HttpContent content = new StringContent("size=" + Data.Length);

            var response = await client.PostAsync(url, content);

            richTextBox1.Text = richTextBox1.Text + ("Step1 : " + response.StatusCode);

            int sendbytes = 0;
            int Var = 1024 * 32;
            int Len = Convert.ToInt32(Data.Length / Var);
            int Counter = 0;

            while (Data.Length > sendbytes)
            {

                //Thread.Sleep(1000);
                if (Counter < Len)
                {
                    array1 = new byte[Var];

                    for (int i = 0; i < array1.Length; i++)
                    {
                        if (sendbytes < Data.Length)
                        {
                            array1[i] = Data[sendbytes];
                            sendbytes++;
                        }
                        else
                        {
                            break;
                        }
                    }
                    Counter++;
                    // textBox1.Text = Counter.ToString();
                }
                else
                {

                    array1 = new byte[Data.Length - (Var * Len)];
                    //textBox1.Text += "Remaining Array Length = " + array1.Length.ToString();
                    for (int i = 0; i < array1.Length; i++)
                    {
                        array1[i] = Data[sendbytes];
                        sendbytes++;
                    }

                }

                ByteArrayContent Bytcontent = new ByteArrayContent(array1);
                Bytcontent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");

                var response1 = await client.PostAsync(url, Bytcontent);
             

                richTextBox1.Text = richTextBox1.Text + (response1.StatusCode);

            }
        }
        catch (Exception ex)
        {
            richTextBox1.Text = richTextBox1.Text + ex.Message;
            richTextBox1.Text = richTextBox1.Text + ex.InnerException;

        }










    }




   



    private void button2_Click(object sender, EventArgs e)
    {
        OpenFileDialog ofd = new OpenFileDialog();

        ofd.Filter = "FWU file|*.fwu*";
        ofd.Title = "Load FWU file";
        if (ofd.ShowDialog() == DialogResult.OK)
        {

            TxT_SelectedFwuFile.Text = ofd.FileName;
        }


    }

    private void Form1_Load(object sender, EventArgs e)
    {
        TxT_SelectedFwuFile.ReadOnly = true;
    }
}

}

enter code here
c# ssl tls1.2 dotnet-httpclient tcpclient
1个回答
0
投票

它可能使用 HTTP 1.1,它不支持多个流。这本身不一定是一个问题。

由于您没有处理请求,因此 HTTP 处理程序认为您仍然想从中读取数据,因此无法使用该连接,这一事实使情况变得更加复杂。因此它会打开另一个。

var response = await client.PostAsync(url, content);
// etc
var response1 = await client.PostAsync(url, Bytcontent);

应该是

using (var response = await client.PostAsync(url, content))
{
    // do stuff with response
}

using (var response1 = await client.PostAsync(url, Bytcontent))
{
    // do stuff with response
}

其他要点:

  • TLS 不应花费 6 秒。与 CRL 服务器的连接可能较差,您可能应该尝试让 Web 服务器使用 OCSP Stapling,这样就不需要 CRL 服务器了。
  • 考虑使用
    Array.Copy
    而不是编写复制循环。
  • 考虑将
    FileStream
    直接传递给
    StreamContent
    ,而不是首先复制到数组中。再次强调,不要忘记丢弃它。
© www.soinside.com 2019 - 2024. All rights reserved.