2012-08-05 25 views
7

Mogę użyć SetBuffer z SocketAsyncEventArgs.W jaki sposób użyć BufferList z SocketAsyncEventArgs i nie uzyskać SokenError InvalidArgument?

Jeśli próbuję użyć BufferList (po wykonaniu SetBuffer (zerowy, 0, 0)) zawsze i natychmiast otrzymuję SocketError InvalidArgument (10022), gdy wykonuję SendAsync na gnieździe.

Nie ma żadnych przykładów ani dokumentacji na temat korzystania z BufferList, a to, co robię, ma sens (w każdym razie).

Czy ktoś może wskazać przykładowy program lub fragment kodu?

mam łzawienie włosy się nad tym i nie mają wiele lewo ...

Oto co robię (e jest SocketAsyncEventArgs i lSocket zasadzie to samo gniazdo używać do SetBuffer który działa)

// 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

Masz większe szanse na uzyskanie odpowiedzi na swoje pytanie, jeśli oznaczysz je językiem, którego używasz. –

+0

Czy wszystkie ArraySegments muszą być częścią tej samej tablicy bajtów fizycznych? Jeśli tak jest, to uczyniłoby BufferList całkiem bezużytecznym. Czy ktoś pomyślnie użył BufferList? – Dave

+0

Ktoś ma tutaj jakieś pomysły? – Dave

Odpowiedz

9

powodem są coraz wyjątek jest, że pod kapturem SocketAsyncEventArgs używa tylko bufory obecne na liście w momencie ustawiania właściwości BufferList. Zasadniczo staramy się wysłać pl pustym buforem z kodem:

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))); 

Zamiast próbować zrobić:

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; 

Takie zachowanie nie jest dobrze udokumentowany w ogóle i może być rozumiane tylko przez patrząc na BufferList kod settera w szczegółach. Za kulisami SocketAsyncEventArgs ma pole tablicowe WSABuffer (do współdziałania z natywnym kodem), w którym kopiuje i przypina odwołania do tablicy bajtów po ustawieniu BufferList. Ponieważ to jest WSABuffer[], który jest wysyłany do kodu natywnego, to wyjaśnia, dlaczego twój kod zgłasza wyjątek.

+0

Dzięki. To ma sens, ale nie jest oczywiste ... – Dave

+1

Zdecydowanie nie, natknąłem się na ten sam problem, gdy znalazłem twój wpis i byłem bardzo rozczarowany, nikt nie odpowiedział. MS powinno naprawdę udokumentować to lepiej. Szkoda, że ​​spóźniłem się z tobą o rok;). – JJ15k