我可以依赖DataAvailable进行SSL封装的网络流吗?

问题描述:

我正在处理大量异步阅读的应用程序。为了提高性能,我希望直接从SslStream进行Read的同步呼叫,前提是呼叫不会阻塞。我可以依赖DataAvailable进行SSL封装的网络流吗?

SslStream本身不提供DataAvailable属性,如底层的NetworkStream

因此,鉴于我知道这是一个包装的网络流正在读取,将trueDataAvailable保证调用SslStream不会导致块?

像这样:

public void Read(NetworkStream netStream, SslStream sslStream) 
{ 
    // given that netStream is the inner stream of sslStream 
    if (netStream.DataAvailable) 
    { 
     // Will not block 
     sslStream.Read(...); 
    } 
    else 
    { 
     // Would block 
     sslStream.Read(...); 
    } 
} 

SslStream已经被验证,并准备去。我不确定除了加密/解密之外是否还有额外的开销。我假设答案依赖于SslStream是否需要从基础流读取多个字节以读取一个加密字节。

不,它不能保证,因为下一层有SSL记录,而且你可能还没有收到完整的记录,而从密码学的角度来说,除非你拥有一切,否则不能做任何事情,如你首先必须检查MAc的完整性目的。

但更重要的是,我质疑整个战略。只需在正常代码中发布所需的读数:不要试图猜测哪种模式在每种情况下都能发挥最佳效果。 SSL开销可能会淹没同步/异步差异,而网络带宽限制会使它们都陷入瘫痪。

+0

谢谢。除非我知道这个流是没有SSL的普通网络流,否则我会一直使用异步阅读。 – Dervall 2012-08-15 06:08:53

它取决于使用中的密码 - 使用RC4或另一个流密码的端点一次可能可解密一个字节,但不能保证。为DES或其他块密码配置的端点将一直等到满块可用。

你可以做一些棘手的东西与一个peekable中间缓冲流,并尝试确保你有一个合理的块大小之前进行阻塞阅读,但这是讨厌的。

如果你绝对不能阻止,我会坚持BeginRead和完成委托。

+0

不确定使用什么密码。我不确定我是否可以检查数据流中的可用数据量,只有在下一次呼叫将被阻止时才可以。这将是非常好的,以避免额外的开销。 – Dervall 2012-08-14 17:20:38

+1

您需要整个SSL记录才能做任何事情,因为您首先必须检查MAC。在检查MAC之前传递任何字节是不正确的,而不正确的则表明它们可用。 – EJP 2012-08-14 23:57:59