我可以从System.Net.Security.SslStream期望安全吗?
我有一个应用程序使用SslStream
以自己的固定长度帧发送和接收数据。 该流是通过包装从TcpClient.GetStream()
返回的NetworkStream
创建的,如下所示:
var client = new TcpClient();
client.Connect(host, port);
var sslStream = new SslStream(client.GetStream(), false, callback, null);
sslStream.AuthenticateAsClient(hostname);
由于该协议是完全异步的(框架“消息”在任意时间到达并且允许客户端在任意时间发送它们),所以我通常会产生一个负责阻塞NetworkStream.Read()
的线程,否则确保只有一个线程在任何时候都调用NetworkStream.Write(...)
。
NetworkStream
的备注部分说:
可以在NetworkStream类的一个实例上同时执行读写操作,而无需同步。 只要有一个唯一的线程用于写入操作并且一个唯一的线程用于读取操作,读写线程之间就不存在交叉干扰,并且不需要同步。
但是, SslStream
的MSDN文档“线程安全”部分说:
此类型的任何公共静态(Visual Basic中的Shared)成员都是线程安全的。 任何实例成员不保证是线程安全的。
由于SslStream
和NetworkStream
不在同一个类层次结构中,因此我假定(可能不正确) NetworkStream
的注释不适用于SslStream
。
对于线程安全来说,最简单的方法是用这样的东西简单地包装SslStream.BeginRead
/ SslStream.EndRead
和SslStream.BeginWrite
/ SslStream.EndWrite
?
internal sealed class StateObject
{
private readonly ManualResetEvent _done = new ManualResetEvent(false);
public int BytesRead { get; set; }
public ManualResetEvent Done { get { return _done; } }
}
internal sealed class SafeSslStream
{
private readonly object _streamLock = new object();
private readonly SslStream _stream;
public SafeSslStream(SslStream stream)
{
_stream = stream;
}
public int Read(byte[] buffer, int offset, int count)
{
var state = new StateObject();
lock (_streamLock)
{
_stream.BeginRead(buffer, offset, count, ReadCallback, state);
}
state.Done.WaitOne();
return state.BytesRead;
}
public void Write(byte[] buffer, int offset, int count)
{
var state = new StateObject();
lock (_streamLock)
{
_stream.BeginWrite(buffer, offset, count, WriteCallback, state);
}
state.Done.WaitOne();
}
private void ReadCallback(IAsyncResult ar)
{
var state = (StateObject)ar.AsyncState;
lock (_streamLock)
{
state.BytesRead = _stream.EndRead(ar);
}
state.Done.Set();
}
private void WriteCallback(IAsyncResult ar)
{
var state = (StateObject)ar.AsyncState;
lock (_streamLock)
{
_stream.EndWrite(ar);
}
state.Done.Set();
}
}
您从MSDN文档中提取的短语是放在大多数类的文档中的全部内容。 如果一个成员的文档明确指出线程安全(就像NetworkStream
一样),那么你可以依靠它。
但是,他们所说的是,您可以同时执行一次读取和一次写入,而不是两次读取或两次写入。 因此,您需要分别对读写进行同步或排队。 你的代码看起来足够做到这一点。
链接地址: http://www.djcxy.com/p/9929.html上一篇: safety can I expect from System.Net.Security.SslStream?