2011-11-01 12 views
7

Ho un'applicazione che utilizza SslStream per inviare e ricevere dati con il proprio frammento di lunghezza fissa. Il flusso è creato avvolgendo il NetworkStream tornato da TcpClient.GetStream() in questo modo:Quale livello di sicurezza del thread posso aspettarmi da System.Net.Security.SslStream?

var client = new TcpClient(); 
client.Connect(host, port); 
var sslStream = new SslStream(client.GetStream(), false, callback, null); 
sslStream.AuthenticateAsClient(hostname); 

Poiché il protocollo è completamente asincrona ("messaggi" incorniciati arrivano a volte arbitrarie e il cliente può inviare loro, a volte arbitrarie), I genererebbe normalmente un thread responsabile per il blocco su NetworkStream.Read() e in caso contrario assicurerà che vi sia un solo thread che chiama NetworkStream.Write(...) in qualsiasi momento.

La sezione Remarks per NetworkStream dice:

lettura e scrittura possono essere eseguite simultaneamente una un'istanza della classe NetworkStream senza necessità di sincronizzazione. Finché c'è un thread univoco per le operazioni di scrittura e un thread univoco per le operazioni di lettura, non ci sarà alcuna interferenza tra i thread di lettura e scrittura e non è richiesta alcuna sincronizzazione.

Tuttavia, la sezione MSDN documentation "thread safe" per SslStream dice:

statici pubblici (in Visual Basic) di questo tipo sono thread-safe . Non è garantito che tutti i membri di istanza siano protetti da thread .

Perché SslStream e NetworkStream non sono nella stessa gerarchia di classe, ho assunto (forse erroneamente) che il commento in NetworkStream non si applicano a SslStream.

è l'approccio migliore per la sicurezza filo per avvolgere semplicemente SslStream.BeginRead/SslStream.EndRead e SslStream.BeginWrite/SslStream.EndWrite con qualcosa di simile?

+0

Dettaglio minuscolo: il blocco su _stream funzionerà ma è consigliabile creare e utilizzare un oggetto separato per questo scopo. –

+0

@HenkHolterman Applausi per il consiglio; Ho aggiornato il codice. –

+0

FWIW: Il [SafeSslStream] (https://github.com/smarkets/IronSmarkets/blob/master/IronSmarkets/Sockets/SafeSslStream.cs) in questione è per [IronSmarkets] (https://github.com/smarkets/IronSmarkets). –

risposta

3

La frase estratta dai documenti MSDN è un elemento che viene inserito nella documentazione della maggior parte delle classi. Se la documentazione di un membro indica esplicitamente la sicurezza del thread (come fa NetworkStream), puoi fare affidamento su di esso.

Tuttavia, ciò che stanno affermando è che è possibile eseguire una lettura e una scrittura contemporaneamente, non due letture o due scritture. Pertanto, dovrai sincronizzare o mettere in coda le tue letture e le tue scritture separatamente. Il tuo codice sembra sufficiente per farlo.

+0

Ciò che ancora mi spiace è che le osservazioni compaiano solo in "NetworkStream" e che "SslStream" non erediti da "NetworkStream", ma invece viene visualizzato quando viene usato con "TcpClient". –

+0

Poiché lo SslStream eseguirà il wrapping di un NetworkStream, si otterrà la sicurezza implicita del thread sulle operazioni di lettura e scrittura in modo indipendente. Se così non fosse, SSL sarebbe half-duplex (che non è). Puoi semplicemente leggere e scrivere nelle loro serrature e sarà sicuro. – Polynomial

+1

Solo per aggiungere un po 'di precisione: mentre la maggior parte di SSL è full duplex, le stringhe di mano richiedono la sincronizzazione delle direzioni di lettura e scrittura; e il client e il server possono richiedere una nuova handshake in qualsiasi momento. Quindi, essere in grado di fare letture in un thread e scrivere nell'altro, senza sincronizzazione, non è una conseguenza ovvia della sicurezza del thread di NetworkStream. Fortunatamente, l'implementazione di Microsoft di SslStream include i blocchi interni necessari per consentire tale operazione bi-thread (non ho controllato Mono, però). –