双工服务器环境中的 SocketAsyncEventArgs?

SocketAsyncEventArgs in a duplex server environment?

我正在通过 MSDN 教程学习使用 SocketAsyncEventArgs 内容。我只是想知道一些事情,即如何实现具有全双工功能的服务器。

目前,MSDN 示例教您创建一个服务器,该服务器首先侦听,然后在收到某些内容时将其发回。 只有服务器才会重新开始侦听。

我想出自己的解决方案的问题是 SocketAsyncEventArgs 对象只有一个事件,Completed 是为 both 触发的发送和接收。它没有其他事件。

我在一些翻译得很糟糕的网站上看到我

must use two SocketAsyncEventArgs, one receives a hair.

-unknown

我发现关于这个所谓的“增强型”套接字实现的信息少得令人不安...

下面是我的一些代码,您可以看看我在做什么。

        //Called when a SocketAsyncEventArgs raises the completed event
        private void ProcessReceive(SocketAsyncEventArgs e)
        {
            Token Token = (Token)e.UserToken;

            if(e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
            {
                Interlocked.Add(ref TotalBytesRead, e.BytesTransferred);
                Console.WriteLine(String.Format("Received from {0}", ((Token)e.UserToken).Socket.RemoteEndPoint.ToString()));

                bool willRaiseEvent = ((Token)e.UserToken).Socket.ReceiveAsync(e);
                if (!willRaiseEvent)
                {
                    ProcessReceive(e);
                }
            }
            else
            {
                CloseClientSocket(e);
            }
        }

        private void ProcessSend(SocketAsyncEventArgs e)
        {
            if (e.SocketError == SocketError.Success)
            {
                // done echoing data back to the client
                Token token = (Token)e.UserToken;
                // read the next block of data send from the client
                bool willRaiseEvent = token.Socket.ReceiveAsync(e);
                if (!willRaiseEvent)
                {
                    ProcessReceive(e);
                }
            }
            else
            {
                CloseClientSocket(e);
            }
        }

        void IOCompleted(object sender, SocketAsyncEventArgs e)
        {
            // determine which type of operation just completed and call the associated handler
            switch (e.LastOperation)
            {
                case SocketAsyncOperation.Receive:
                    ProcessReceive(e);
                    break;
                case SocketAsyncOperation.Send:
                    ProcessSend(e);
                    break;
                default:
                    throw new ArgumentException("The last operation completed on the socket was not a receive or send");
            }

        }

谢谢!

解决方案是为 SendReceive 创建一个单独的 SocketAsyncEventArgs

它需要更多的内存但并不多,因为不需要为 Send args 分配缓冲区。