【问题标题】:SslStream.Read results in IOExceptionSslStream.Read 导致 IOException
【发布时间】:2014-06-25 20:17:15
【问题描述】:

我正在尝试使用 SslStream 连接到网站以传递请求,但我收到以下 IOException:

无法从传输连接中读取数据:连接尝试失败,因为连接方在一段时间后没有正确响应,或者连接失败,因为连接的主机没有响应。

为了让测试更高效,我创建了一个独立程序并从这里复制了客户端代码示例代码:http://msdn.microsoft.com/en-us/library/system.net.security.sslstream(v=vs.110).aspx,然后根据对方的 API 传入请求。

            string Request = "The Request";
            TcpClient client = new TcpClient();
            client.ReceiveTimeout = 10000; //10 seconds
            SslStream sslStream;
            string server = "ssl.website.com";
            client.Connect(server, 12345);
            sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null );

            sslStream.AuthenticateAsClient(server,null, SslProtocols.Tls12, false);

            StringBuilder messageData = new StringBuilder();
            byte[] len = BitConverter.GetBytes(SslClient.GetLen(Request));

            messageData.AppendLine("Writing length of data " + SslClient.GetLen(Request).ToString());
            sslStream.Write(len);
            byte[] msg = Encoding.UTF8.GetBytes(Request);

            sslStream.Write(msg);
            sslStream.Flush();

            byte[] buffer = new byte[2048];

            messageData.AppendLine("Writing data " + System.Text.Encoding.UTF8.GetString(msg));
            messageData.AppendLine("Is Authenticated? " + sslStream.IsAuthenticated.ToString());
            int bytes = -1;

            try
            {
                do
                {
                    bytes = sslStream.Read(buffer, 0, buffer.Length);

                    Decoder decoder = Encoding.UTF8.GetDecoder();
                    char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
                    decoder.GetChars(buffer, 0, bytes, chars, 0);
                    messageData.AppendLine(chars.ToString());

                    if (messageData.ToString().IndexOf("<EOF>") != -1)
                    {
                        break;
                    }

                } while (bytes != 0);
            }
            catch(Exception ex)
            {
                messageData.AppendLine(ex.Message);
            }

            return messageData.ToString();
        }


        public static bool ValidateServerCertificate(
              object sender,
              X509Certificate certificate,
              X509Chain chain,
              SslPolicyErrors sslPolicyErrors)
        {
            if (sslPolicyErrors == SslPolicyErrors.None)
                return true;
            return false;
        }

        public static Int16 GetLen(string Request)
        {
            return Convert.ToInt16(Encoding.UTF8.GetBytes(Request).Length);

        }

失败的部分是 sslStream.Read(buffer, 0, buffer.Length)。这永远不会返回,并且是 IOException 的来源。

我试图联系的人说 SSL 握手失败,但我看不到任何迹象。它总是使它成为 sslStread.Read 然后失败。他们说有时他们正在接收请求并发送响应,但我还没有看到返回的响应。

谢谢

【问题讨论】:

  • 请在您的帖子中嵌入示例并解释为什么您不能使用现有的WebClient/HttpWebRequest 类。
  • 好的,我添加了代码。这几乎只是复制那个 MSDN 示例。我应该使用 WebClient / HttpWebRequest 吗?
  • 除非您有充分的理由使用SslStream 这样的低级API,否则我建议使用WebClient 来发送Web 请求。为了调试您的代码 - 检查端口/dns 是否正确,并查看是否调用了 ValidateServerCertificate。
  • 我验证了 validateServerCertificate 正在被调用。它导致 SslPolicyErrors.None,所以没有问题。我只是尝试使用 WebClient 没有成功。它超时。我会把我的代码放在上面。
  • 代码看起来不错。该服务可能没有与代码相关的问题。不知道接下来应该采取什么步骤。

标签: c# .net sslstream


【解决方案1】:

在与合作伙伴进行了一些测试后,结果证明这是我的代码中的一个简单错误。长度字节必须翻转到网络字节顺序。我使用 IPAddress.HostToNetworkOrder 完成此操作

            byte[] len = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(SslClient.GetLen(Request)));

            messageData.AppendLine("Writing length of data " + SslClient.GetLen(Request).ToString());
            sslStream.Write(len);

【讨论】:

    猜你喜欢
    • 2021-01-01
    • 1970-01-01
    • 2012-03-28
    • 2015-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-05
    • 2012-04-29
    相关资源
    最近更新 更多