I can use SetBuffer with SocketAsyncEventArgs just fine.
If I try to use BufferList (after doing SetBuffer(null, 0, 0)) I always and immediately get SocketError InvalidArgument (10022) when I do SendAsync on the socket.
There are NO examples or documentation on how to use BufferList and what I am doing makes sense (to me anyway).
Can someone point out an example program or code snippet?
I'm tearing my hair out over this and don't have much left ...
Here is basically what I am doing (e is SocketAsyncEventArgs and lSocket is the same socket I use for SetBuffer which works)
// 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);
}
The reason you are getting an exception is that under the hood the
SocketAsyncEventArgs
only uses the buffers present in the list at the time of setting theBufferList
property. Basically you are trying to send en empty buffer with the code :Instead try to do :
This behavior is not well documented at all and can only be understood by looking at the
BufferList
setter code in detail. Behind the scenes theSocketAsyncEventArgs
has aWSABuffer
array field(for interop with native code) where it copies and pins the byte arrays references when you set theBufferList
. Since it is thisWSABuffer[]
that is sent to native code, that explains why your code throws an exception.