gpt4 book ai didi

c# - 如何通过 SslStream 和 TcpClient 向 Web 服务发送有效的 HTTPS 请求

转载 作者:太空宇宙 更新时间:2023-11-03 12:57:22 28 4
gpt4 key购买 nike

我实际上是在尝试设置一个 HTTPS 客户端,我可以使用它来自动测试 API 和我正在开发的其他网络服务。我熟悉使用套接字,但不太熟悉在代码中使用 SSL/TLS。我首先尝试设置一个客户端,该客户端使用以下 header 向 google.com 发送 HTTP 请求:GET/HTTP/1.1

当然,我们的想法是通过加密连接接收来自 Google 的基本 HTTP 响应。当使用未加密的 HTTP 时,这真的很容易——我什至可以通过端口 80 telnet 到 google 并输入 GET/HTTP/1.1,我会收到一个很好的 HTTP 响应 header 和 HTML 负载。实现用于发出未加密的 HTTP 请求的 C/C# 代码也不是很困难。 SSL 给我带来了困难。

使用下面的代码(在 https://msdn.microsoft.com/en-us/library/system.net.security.sslstream.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-3 找到的完整示例),它与 MSDN 提供的引用实现几乎相同,我可以成功连接到 google.com 并验证服务器证书:

        // Create a TCP/IP client socket.
// machineName is the host running the server application.
TcpClient client = new TcpClient(machineName, 443);
Console.WriteLine("Client connected.");
// Create an SSL stream that will close the client's stream.
SslStream sslStream = new SslStream(
client.GetStream(),
false,
new RemoteCertificateValidationCallback(ValidateServerCertificate),
null
);
// The server name must match the name on the server certificate.
try
{
sslStream.AuthenticateAsClient(serverName);
}
catch (AuthenticationException e)
{
Console.WriteLine("Exception: {0}", e.Message);
if (e.InnerException != null)
{
Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
}
Console.WriteLine("Authentication failed - closing the connection.");
client.Close();
return;
}

问题是当执行以下代码时,ReadMessage(sslStream) 指令挂起,因为我很长时间没有收到响应,而当响应最终到达时它是一个空字符串:

        // Encode a test message into a byte array.
// Signal the end of the message using the "<EOF>".
byte[] messsage = Encoding.UTF8.GetBytes("GET / HTTP/1.1<EOF>");
// Send hello message to the server.
sslStream.Write(messsage);
sslStream.Flush();
// Read message from the server.
string serverMessage = ReadMessage(sslStream);
Console.WriteLine("Server says: {0}", serverMessage);

因此,当我通过安全套接字连接发出此请求时,我无法收到我正在寻找的 HTTP 响应(或任何东西)。从长远来看,我的想法是开始使用此客户端向我自己的 API 和 Web 服务发送定制的 HTTP 请求,但如果我什至无法从 google.com 获得通用响应,我当然无法做到这一点。有谁知道为什么 ReadMessage() 函数超时或不提供响应?示例代码看起来非常简单,所以我很难理解我做错了什么。

最佳答案

立即引起我注意的一件事是 Microsoft 示例没有为 sslStream.Write() 提供“计数”参数,我认为这可能与您的问题有关。另请注意,ReadMessage() 似乎是您尚未为其提供定义的函数。如果不知道 ReadMessage() 具体在做什么,则无法确定问题的确切原因。我修改了提供的用于发送 HTTPS 请求和读取响应的代码。它似乎适用于我迄今为止尝试过的网站。

        // Send request
byte[] buffer = new byte[2048];
int bytes;
byte[] request = Encoding.UTF8.GetBytes(String.Format("GET https://{0}/ HTTP/1.1\r\nHost: {0}\r\n\r\n", serverName));
sslStream.Write(request, 0, request.Length);
sslStream.Flush();

// Read response
do
{
bytes = sslStream.Read(buffer, 0, buffer.Length);
Console.Write(Encoding.UTF8.GetString(buffer, 0, bytes));
} while (bytes == 2048);

作为旁注,我还注意到 sslStream.AuthenticateAsClient(serverName); 这当然适用于许多 Web 服务;但是,在访问严格使用 TLS1.2 的站点时,我遇到了特定重载的问题。如果您想启用对严格 TLS1.2 代理的支持,请尝试 sslStream.AuthenticateAsClient(serverName,null,SslProtocols.Tls12,false);

关于c# - 如何通过 SslStream 和 TcpClient 向 Web 服务发送有效的 HTTPS 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41228210/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com