2012-08-05 9 views
7

Posso usare SetBuffer con SocketAsyncEventArgs bene.Come utilizzare BufferList con SocketAsyncEventArgs e non ottenere SocketError InvalidArgument?

Se provo a utilizzare BufferList (dopo aver eseguito SetBuffer (null, 0, 0)) ottengo sempre e immediatamente SocketError InvalidArgument (10022) quando eseguo SendAsync sul socket.

Non ci sono esempi o documentazione su come usare BufferList e quello che sto facendo ha senso (per me comunque).

Qualcuno può indicare un programma di esempio o uno snippet di codice?

Sto strappando i capelli su questo e non hanno molto lasciato ...

Qui è fondamentalmente quello che sto facendo (e è SocketAsyncEventArgs e lSocket è lo stesso socket che uso per SetBuffer che funziona)

// null the buffer since we will use a buffer list 
e.SetBuffer(null, 0, 0); 

// create a bufferlist 
e.BufferList = new List<ArraySegment<byte>>(); 

// create the bufferlist with the network header and the response bytes 
e.BufferList.Add(new ArraySegment<byte>(lTxBytes)); // add the 4 character total length 
e.BufferList.Add(new ArraySegment<byte>(Encoding.ASCII.GetBytes(lTx.Identity))); // echo back the incoming sequence number 
e.BufferList.Add(new ArraySegment<byte>(Encoding.ASCII.GetBytes(lResponse))); 

// *** the SendAsync always completes IMMEDIATELY (returns false) gets SocketError InvalidArgument (10022) 

if (lSocket.SendAsync(e) == false) 
{ 
     // data was already sent back to the client. 
     AppSupport.WriteLog(LogLevel.Flow, "ProcessReceive had SendAsync complete synchronously (bytes transferred {0}).", e.BytesTransferred); 
     ProcessSend(e); 
} 
+0

Hai una migliore possibilità di ottenere risposta per la tua domanda se la tagghi con la lingua che usi. –

+0

Tutti i segmenti di array devono far parte dello stesso array di byte fisici? Se questo è il caso, renderebbe BufferList abbastanza inutile. Qualcuno ha usato BufferList con successo? – Dave

+0

Qualcuno ha qualche idea qui? – Dave

risposta

9

la ragione si stanno ottenendo un'eccezione è che sotto il cofano della SocketAsyncEventArgs utilizza solo i buffer presenti nella lista, al momento dell'impostazione della proprietà BufferList. Fondamentalmente si sta tentando di inviare it buffer vuoto con il codice:

e.BufferList = new List<ArraySegment<byte>>(); 
e.BufferList.Add(new ArraySegment<byte>(lTxBytes)); 
e.BufferList.Add(new ArraySegment<byte>(Encoding.ASCII.GetBytes(lTx.Identity))); 
e.BufferList.Add(new ArraySegment<byte>(Encoding.ASCII.GetBytes(lResponse))); 

Invece cercare di fare:

var list = new List<ArraySegment<byte>>(); 
list.Add(new ArraySegment<byte>(lTxBytes)); 
list.Add(new ArraySegment<byte>(Encoding.ASCII.GetBytes(lTx.Identity))); 
list.Add(new ArraySegment<byte>(Encoding.ASCII.GetBytes(lResponse))); 
e.BufferList = list; 

Questo comportamento non è ben documentato a tutti e può essere compreso solo guardando il BufferList codice setter in dettaglio. Dietro le quinte il SocketAsyncEventArgs ha un campo di matrice WSABuffer (per l'interoperabilità con il codice nativo) dove copia e applica i riferimenti ai matrici di byte quando si imposta BufferList. Dal momento che è questo WSABuffer[] che viene inviato al codice nativo, questo spiega perché il tuo codice genera un'eccezione.

+0

Grazie. Ha senso ma non è ovvio ... – Dave

+1

Sicuramente no, stavo incontrando lo stesso problema quando ho trovato il tuo post ed ero molto deluso a nessuno aveva risposto. MS dovrebbe davvero documentarlo meglio. Peccato, sono un anno dopo averti risposto;). – JJ15k

Problemi correlati