-1

there is an interface IStream to abstract NetworkStream and SslStream. With NetworkStream everything is fine while with SslStream having problems on Read method. This is how I establish Ssl stream:

class SecureStream : SslStream, IStream
{
    TcpClient _tcpClient;
    public SecureStream(TcpClient tcpClient) : base(tcpClient.GetStream()) {
        _tcpClient = tcpClient;
        var serverCertificate = new X509Certificate(@"C:\Cert.cer");
        AuthenticateAsServer(serverCertificate);
        ReadTimeout = -1;
        this.InnerStream.ReadTimeout = -1;
        _tcpClient.Client.ReceiveTimeout = -1;
    }
    ...
}

After successful reading some portion of data (http header) have to wait several seconds on Read method, but Read method instantly returns 0. Ssl connection stays active and I can Write response back on other thread. What reasons could be that Read method not waiting for data to appear in stream?

Jonas
  • 4,683
  • 4
  • 45
  • 81
  • 2
    When `Read` returns 0, it means the other side has shutdown the connection. That's all there is to it. And oh god, please, don't do stuff like this in a constructor. Finding an article on how to handle SSL properly might be a better idea than trying to find something that works on your own. – Luaan Feb 15 '16 at 13:22
  • I concur, SSL connections are tricky. I had an issue that only appeared with a Linux/OpenSSL implementation on the server. It's better to stick to existing code samples than coming up with your own creation. – pid Feb 15 '16 at 13:25
  • Other side is connected, while Read returns 0 I can successfully write to the same Ssl stream. What is the reason that establishing SSL connection in a constructor is so evil? – Jonas Feb 15 '16 at 13:33
  • 1
    First, make sure to reference who you're responding to, like @Jonas TCP allows you to have the connection closed from one side while the other remains open - you can have a Client -> Server, Server -> Client or Client <-> Server TCP connection. As for the constructor... ouch. `AuthenticateAsServer` is a virtual method, as is `ReadTimeout`. Calling virtual methods from a constructor is a big no-no. Apart from that, you're doing *I/O* work in the constructor. Constructors shouldn't really do much - you might want to use a static method for this instead. Also, composition is worth looking into. – Luaan Feb 15 '16 at 16:05
  • OK I will refactor and change interface to abstract class and will encapsulate streams in implementations. But my guess is that it will not solve this problem because right now I have a successful SSL connection and can read and write data throw it. Or am I wrong, it is possible partly (just one direction) disconnect SSL stream? – Jonas Feb 15 '16 at 18:59

1 Answers1

0

Turns out that for such behavior responsible SSL stream establishment inside constructor (thanks Luaan). Encapsulated SslStream version works as expected.

Jonas
  • 4,683
  • 4
  • 45
  • 81