7

我可以使用 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);
}
4

1 回答 1

12

您遇到异常的原因是,在设置属性SocketAsyncEventArgs时,仅使用列表中存在的缓冲区。BufferList基本上,您正在尝试使用代码发送空缓冲区:

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[]发送到本机代码的,这就解释了为什么您的代码会引发异常。

于 2013-07-02T09:44:04.920 回答