How to use BufferList with SocketAsyncEventArgs and not get SocketError InvalidArgument?

I can use SetBuffer with SocketAsyncEventArgs just fine.

If I try to use a BufferList (after executing SetBuffer (null, 0, 0)), I always and immediately get SocketError InvalidArgument (10022) when I find SendAsync in the socket.

There are NO examples or documentation on how to use the BufferList, and what I am doing makes sense (for me anyway).

Can someone provide an example program or piece of code?

I tear my hair from it and don’t leave much ...

Here is basically what I'm doing (e SocketAsyncEventArgs and lSocket are the same socket that 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); } 
+7
source share
1 answer

The reason you get the exception is because under the hood of SocketAsyncEventArgs , only the buffers that are in the list when setting the BufferList property are BufferList . Basically you are trying to send an empty buffer with code:

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

Instead, try doing:

 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; 

This behavior is not documented at all and can only be understood by looking at the set BufferList code in detail. Behind the scenes, SocketAsyncEventArgs has a WSABuffer array WSABuffer (for interacting with native code), where it copies and provides links to byte arrays when setting BufferList . Since this WSABuffer[] sent in native code, this explains why your code throws an exception.

+9
source

All Articles