SslStream.Чтение результатов в IOException

#c# #.net #sslstream

#c# #.net #sslstream

Вопрос:

Я пытаюсь использовать 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 .Длина). Это никогда не возвращается и является источником IOException.

Люди, с которыми я пытаюсь подключиться, говорят, что SSL-квитирование не выполняется, но я не вижу никаких признаков этого с нашей стороны. Он всегда попадает в sslStread .Чтение, а затем сбой. Они сказали, что иногда они получают запрос и отправляют ответ, но я еще не видел возвращенного ответа.

Спасибо

Комментарии:

1. Пожалуйста, вставьте пример в свой пост и объясните, почему вы не можете использовать существующие / классы. WebClient HttpWebRequest

2. Хорошо, я добавил код. Это в значительной степени просто копирование этого примера MSDN. Должен ли я использовать WebClient / HttpWebRequest?

3. Если у вас нет веских оснований использовать такой низкоуровневый API, SslStream который я бы рекомендовал использовать WebClient для отправки веб-запросов. Для отладки вашего кода проверьте правильность порта / dns и посмотрите, вызывается ли ValidateServerCertificate.

4. Я проверил, что вызывается validateServerCertificate . Это приводит к sslPolicyErrors.None, так что никаких проблем. Я только что безуспешно пытался использовать WebClient. Время ожидания истекло. Я приведу свой код для этого выше.

5. Код выглядит нормально. Скорее всего, проблема с сервисом не связана с кодом. Не уверен, какие следующие шаги вам следует предпринять.

Ответ №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);