2010-06-22 10 views
8

Questo mi lascia perplesso. Ho un errore sulla ricerca quando non lo chiamo nemmeno?Perché BufferedStream.Write genera "Questo stream non supporta le operazioni di ricerca"?

Ho codice che sembra qualcosa di simile:

// send 42 
uint value = 42; 
byte[] msg = BitConverter.GetBytes(value); 
stream.Write(msg, 0, sizeof(uint)); 

e ottengo questa eccezione:

System.NotSupportedException was unhandled 
Message="This stream does not support seek operations." 
Source="System" 
StackTrace: 
    at System.Net.Sockets.NetworkStream.Seek(Int64 offset, SeekOrigin origin) 
    at System.IO.BufferedStream.FlushRead() 
    at System.IO.BufferedStream.Write(Byte[] array, Int32 offset, Int32 count) 
... 

flusso è di tipo System.IO.BufferedStream. Cosa potrebbe succedere?

di modifica con maggiori informazioni:

sizeof(uint)==msg.length in questo caso.
Il flusso è dichiarato come stream = new BufferedStream(new NetworkStream(socket), 1024)

edit:

che è stato! Mentre è possibile leggere e scrivere su un singolo NetworkStream, quando si passa a un BufferedStream è necessario disporre di uno separato per la lettura e la scrittura. Apparentemente si può chiamare il costruttore NetworkStream due volte sullo stesso socket per ottenere quello.

Accetterei entrambe le risposte di Justin e Hans se potessi, perché uno mi ha permesso di capire esattamente cosa c'era di sbagliato, e l'altro mi ha portato alla soluzione. Grazie a tutti!

+0

Nel caso in cui questo aiuti, BufferedStream è in cima a un NetworkStream. – redtuna

+0

come hai dichiarato lo stream bufferizzato e quale dimensione? A quale tipo di streaming è associato? e non dovrebbe sizeof (uint) essere msg.length? –

risposta

9

Il problema sta nel funzionamento interno di BufferedStream (e nel fatto che potresti aver usato BufferedStream da leggere prima di tentare di scriverlo).

Quando si tenta di scrivere su un BufferedStream, dopo la convalida i parametri, le cose sono verificati in questo ordine (tutto il codice estratto dal quadro mediante Reflector):


siamo alla mendicità del write buffer?

if(this._writePos == 0) 

Siamo autorizzati a scrivere nel flusso sottostante?

if(!this._s.CanWrite) // throw error 

Il buffer di lettura è vuoto?

if(this._readPos < this._readLen) 
{ 
    // FlushRead() will attempt to call Seek() 
    this.FlushRead(); 
} 

Se ci sono dati da leggere nel buffer di lettura, una Scala viene tentata prima di scrivere. FlushRead() chiama Seek(), che causa l'errore.

+0

ok, quindi non posso chiamare write quando ci sono dati non letti ... il che significa in sostanza che non posso avere un thread letto e l'altro scrivere sullo stesso BufferedStream. Ora, dato che ho un NetworkStream quando mi collego all'altro computer, come faccio a ottenere due BufferedStreams? – redtuna

+0

@redtuna - Se questo è il tuo obiettivo, dovrai creare due NetworkStreams per abbinare i due BufferedStreams. In caso contrario, eseguirai un'intera serie di problemi con il NetworkStream condiviso. –

+0

grazie @Justin. – redtuna

4

È necessario aver letto prima da BufferedStream. Sta ottenendo i suoi byte da un NetworkStream. Quelli sono a senso unico, si può solo leggere o solo scrivere su di essi, a seconda di come sono stati creati. Pubblica il codice che ha creato NetworkStream se hai bisogno di ulteriore aiuto.

+0

Potrebbe esserci qualcosa: è possibile che un altro thread stia cercando di leggere allo stesso tempo, e questo sarebbe il problema.I documenti dicono che puoi sia leggere che scrivere dallo stesso BufferedStream (e nel caso mio, sia. Canan sia. CananWrite sono veri) ma forse non allo stesso tempo. – redtuna

+0

Dovresti avere due NetworkStreams e due BufferedStreams, se sto capendo correttamente il punto. Leggi da uno e scrivi all'altro. –

+0

@red: sì, BufferedStream supporta la lettura e la scrittura. Ma il flusso che sta leggendo/scrivendo potrebbe non supportarlo. NetworkStream no. –

Problemi correlati