如何使用SocketAsyncEventArgs类

 我来答
huanglenzhi
2014-12-16 · 知道合伙人数码行家
huanglenzhi
知道合伙人数码行家
采纳数:117538 获赞数:517198
长期从事计算机组装,维护,网络组建及管理。对计算机硬件、操作系统安装、典型网络设备具有详细认知。

向TA提问 私信TA
展开全部

  由于减少了阻塞线程,高性能I/O限制应用中广泛使用异步编程模型(AMP,Asynchronous Programming Model)。.NET Framework第一个版本就实现了APM,现在使用诸如lambda表达式等新的技术C#3.0一直在改进其性能。针对Socket编程,不仅性能上 提升了不少,而且新APM模型发布了一个更简易的编程方法,该方法使用SocketAsyncEventArgs类来保持I/O操作之间的上下文,从而降低对象分配和垃圾收集工作。

  在.NET 2.0 SP1上可以使用SocketAsyncEventArgs类,本文的代码就是用Microsoft Visual Studio .NET 2005编写的。

  使用代码

  从SocketAsyncEventArgs类开始,我学习了MSDN上 的样例程序,但该文缺少一些内容:AsyncUserToken类。我认为这个类应该公开一个Socket属性,它对应执行I/O操作的Socket。一 段时间后,我认识到这个类不是必要的,因为属性UserToken是一个Object,它可以接受任何东西。下面的修改方法中直接使用一个Socket实 例当作UserToken。

  

  我修改了如何操作侦听者收到消息的代码——不是简单地回发给客户端(参见ProcessReceive方法)。在样例程序中,我使用属性Buffer、Offset与BytesTransfered来接收消息,SetBuffer方法把修改后的消息回返给客户端。 为了控制侦听者生存期时间,使用了一个Mutex类的实例。基于原Init方法的Start方法创建Mutex对象,相应的Stop方法释放Mutex对象。这些方法适用于实现作为Windows服务的Socket服务器。

  现在,我们有了一个Socket服务器,下一步使用SocketAsyncEventArgs类建立一个Socket客户端。虽然MSDN说这个类特别设计给网络服务器应用,但也没有限制在客户端代码中使用APM。下面给出了SocketClient类的样例代码:

    //  失败时关闭Socket,根据SocketError抛出异常。
        private void ProcessError(SocketAsyncEventArgs e)
        {
            Socket s = e.UserToken as Socket;
            if (s.Connected)
            {
                //  关闭与客户端关联的Socket
                try
                {
                    s.Shutdown(SocketShutdown.Both);
                }
                catch (Exception)
                {
                    //  如果客户端处理已经关闭,抛出异常
                }
                finally
                {
                    if (s.Connected)
                    {
                        s.Close();
                    }
                }
            }

            //  抛出SocketException
            throw new SocketException((Int32)e.SocketError);
        }

        //  与主机交换消息。
        internal String SendReceive(String message)
        {
            if (connected)
            {
                //  创建一个发送缓冲区。
                Byte [] sendBuffer = Encoding.ASCII.GetBytes(message);

                //  准备发送/接收操作的参数。
                SocketAsyncEventArgs completeArgs = new SocketAsyncEventArgs();
                completeArgs.SetBuffer(sendBuffer, 0, sendBuffer.Length);
                completeArgs.UserToken = clientSocket;
                completeArgs.RemoteEndPoint = hostEndPoint;
                completeArgs.Completed +=
                  new EventHandler<socketasynceventargs>(OnSend);

                //  开始异步发送。
                clientSocket.SendAsync(completeArgs);

                //  等待发送/接收完成。
                AutoResetEvent.WaitAll(autoSendReceiveEvents);

                //  从SocketAsyncEventArgs缓冲区返回数据。
                return Encoding.ASCII.GetString(completeArgs.Buffer,
                       completeArgs.Offset, completeArgs.BytesTransferred);
            }
            else
            {
                throw new SocketException((Int32)SocketError.NotConnected);
            }
        }

        #region IDisposable Members

        // 释放SocketClient实例。
        public void Dispose()
        {
            autoConnectEvent.Close();
            autoSendReceiveEvents[SendOperation].Close();
            autoSendReceiveEvents[ReceiveOperation].Close();
            if (clientSocket.Connected)
            {
                clientSocket.Close();
            }
        }

        #endregion
    }
} 转载仅供参考,版权属于原作者。祝你愉快,满意请采纳哦

推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式