SslStream.Read приводит к IOException

Я пытаюсь использовать SslStream для подключения к веб-сайту для передачи запроса, но получаю следующее IOException:

Невозможно прочитать данные из транспортного соединения: попытка подключения не удалась, потому что подключенная сторона не ответила должным образом через некоторое время, или не удалось установить соединение, потому что подключенный хост не смог ответить.

Чтобы сделать тестирование более эффективным, я создал отдельную программу и скопировал код примера клиентского кода отсюда: http://msdn.microsoft.com/en-us/library/system.net.security.sslstream%28v=vs.110%29.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 и затем терпит неудачу. Иногда они говорят, что получают запрос и отправляют ответ, но я еще не видел ответ.

Спасибо

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);
Другие вопросы по тегам