[转]SocketAsyncEventArgs 单机测试成功突破 6W

SocketAsyncEventArgs 单机测试成功突破 6W,59999 还是 100%连接上去的 所以估计最高性能可能达到10W以上

请看图吧  由于页宽不够 不能够全显示不过你可以另存为图片查看

实现原理:

 

 

          采用 SocketAsyncEventArgs 池 和内存池实现.

 

        代码:

/// <summary>
        /// 启动
        /// </summary>
        public void Start()
        {
            if (isDisposed == true)
            {
                throw new ObjectDisposedException("ZYServer is Disposed");
            }

            sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);

            IPEndPoint myEnd = (String.IsNullOrEmpty(Host)) ? (new IPEndPoint(Dns.GetHostEntry(Dns.GetHostName()).AddressList[0], Port)) : (new IPEndPoint(IPAddress.Parse(Host), Port));

            sock.Bind(myEnd);
            sock.Listen(20);
            SendTimeout = 1000;
            ReceiveTimeout = 1000;

            BuffManagers = new BufferManager(MaxConnectCout * MaxBufferSize, MaxBufferSize);
            BuffManagers.Inint();

            SocketAsynPool = new SocketAsyncEventArgsPool(MaxConnectCout);

            for (int i = 0; i < MaxConnectCout; i++)
            {
                SocketAsyncEventArgs socketasyn = new SocketAsyncEventArgs();
                socketasyn.Completed += new EventHandler<SocketAsyncEventArgs>(Asyn_Completed);
                SocketAsynPool.Push(socketasyn);
            }

            Accept();
        }



        void Accept()
        {
            if (SocketAsynPool.Count > 0)
            {
                SocketAsyncEventArgs sockasyn = SocketAsynPool.Pop();
                if (!Sock.AcceptAsync(sockasyn))
                {
                    BeginAccep(sockasyn);
                }
            }
            else
            {
                LogOutEvent(null, LogType.Error, "The MaxUserCout");
            }
        }

        void BeginAccep(SocketAsyncEventArgs e)
        {
            try
            {

                if (e.SocketError == SocketError.Success)
                {
                   

                    if (this.Connetions != null)
                        if (!this.Connetions(e))
                        {

                            LogOutEvent(null, LogType.Error, string.Format("The Socket Not Connect {0}", e.AcceptSocket.RemoteEndPoint));
                            e.AcceptSocket = null;
                            SocketAsynPool.Push(e);

                            return;
                        }

                   

                    if (BuffManagers.SetBuffer(e))
                    {
                        if (!e.AcceptSocket.ReceiveAsync(e))
                        {
                            BeginReceive(e);
                        }
                       
                    }

                }
                else
                {
                    e.AcceptSocket = null;
                    SocketAsynPool.Push(e);                 
                    LogOutEvent(null, LogType.Error, "Not Accep");
                }
            }
            finally
            {
                Accept();
            }

        }

       


        void BeginReceive(SocketAsyncEventArgs e)
        {
            if (e.SocketError == SocketError.Success&&e.BytesTransferred>0)
            {
                byte[] data = new byte[e.BytesTransferred];

                Array.Copy(e.Buffer, e.Offset, data, 0, data.Length);

                if (this.BinaryInput != null)
                    this.BinaryInput.BeginInvoke(data, e, RecevieCallBack, BinaryInput);

                if (!e.AcceptSocket.ReceiveAsync(e))
                {
                    BeginReceive(e);
                }
            }
            else
            {
                string message=string.Format("User Disconnect :{0}", e.AcceptSocket.RemoteEndPoint.ToString());

                LogOutEvent(null, LogType.Error, message);

                if (MessageInput != null)
                {
                    MessageInput(message, e, 0);
                }

                e.AcceptSocket = null;
                BuffManagers.FreeBuffer(e);
                SocketAsynPool.Push(e);
                if (SocketAsynPool.Count == 1)
                {
                    Accept();
                }
            }

        }

        void RecevieCallBack(IAsyncResult result)
        {
            this.BinaryInput.EndInvoke(result);

        }

        void Asyn_Completed(object sender, SocketAsyncEventArgs e)
        {
            switch (e.LastOperation)
            {
                case SocketAsyncOperation.Accept:
                    BeginAccep(e);
                    break;
                case SocketAsyncOperation.Receive:
                    BeginReceive(e);
                    break;
               
            }
            
        }

 

不用问太多 我也不讲 太多 代码是如此的简单

 

值得说明的是  建议使用 SocketAsyncEventArgs 进行监听的 读取数据包. 因为 这2个地方的 SocketAsyncEventArgs 是同一个,并且内存和 SocketAsyncEventArgs 对象都好回收 好控制

 

如果使用 SocketAsyncEventArgs 发送数据包那么 SocketAsyncEventArgs 就不好控制了 所以使用传统的异步模式比较好. 而数据包传出使用 异步代理 进行传出以免堵塞 SocketAsyncEventArgs 线程.

 

MSND 的 SocketAsyncEventArgs 除了SocketAsyncEventArgsPOOL 和内存Manager 其他纯属扯淡.最好别效仿.

 

 源代码下载地址: http://download.csdn.net/source/2653920

博客地址:http://blog.csdn.net/luyikk/article/details/5081133

posted @ 2015-01-10 15:11  Net-Spider  阅读(296)  评论(0编辑  收藏  举报