如何将BufferList与SocketAsyncEventArgs一起使用而不获取SocketError Invali



我可以将SetBuffer与SocketAsyncEventArgs一起使用。

如果我尝试使用BufferList(在执行SetBuffer(null,0,0)之后),当我对套接字执行SendAsync时,我总是立即获得SocketError InvalidArgument(10022)。

没有关于如何使用BufferList的例子或文档,我所做的事情(无论如何对我来说)是有意义的。

有人能指出一个示例程序或代码片段吗?

我为这件事伤透了脑筋,已经所剩无几了。。。

这基本上是我正在做的(e是SocketAsyncEventArgs,lSocket是我用于SetBuffer的同一个套接字,它起作用)

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

出现异常的原因是,在设置BufferList属性时,SocketAsyncEventArgs只使用列表中存在的缓冲区。基本上,你试图发送一个空的缓冲区,代码是:

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

相反,尝试做:

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;

这种行为根本没有得到很好的记录,只能通过详细查看BufferList setter代码来理解。在幕后,SocketAsyncEventArgs有一个WSABuffer数组字段(用于与本机代码的互操作),当您设置BufferList时,它会在其中复制和固定字节数组引用。由于正是这个WSABuffer[]被发送到本机代码,这就解释了代码抛出异常的原因。

相关内容

  • 没有找到相关文章

最新更新