当前位置:编程学习 > C#/ASP.NET >>

SOCKET 客户端求改进。大家都来看看。


    /// <summary>
    /// TCP服务端类
    /// </summary>
    public class SocketService : IDisposable
    {
        /// <summary>
        /// 套接字服务处理类。
        /// </summary>
        public class EventHandler
        {
            private SocketService s;
            private TaskFactory tf = new TaskFactory(TaskCreationOptions.None, TaskContinuationOptions.None);

            /// <summary>
            /// 构造函数。
            /// </summary>
            /// <param name="socketService"></param>
            public EventHandler(SocketService socketService)
            {
                this.s = socketService;
            }

            /// <summary>
            /// Connections the specified c.
            /// </summary>
            /// <param name="c">The c.</param>
            public void Connection(SocketClient c)
            {
                if (s.OnConnection != null)
                {
                    s.OnConnection(s, new ClientConnectionEventArgs(s, c));
                }
                if (s.ServiceHandler != null)
                {
                    tf.StartNew(() =>
                    {
                        try
                        {
                            s.ServiceHandler.SocketOpened(c);
                        }
                        catch (AggregateException ae)
                        {
                            ae.Handle((e) => { Logger.Instance.Error("套接字处理消息程序异常。", e); return true; });
                        }
                    });
                }
            }

            /// <summary>
            /// 客户断开。
            /// </summary>
            /// <param name="c"></param>
            public void Disconnect(SocketClient c)
            {
                if (s.OnDisconnect != null)
                {
                    s.OnDisconnect(s, new ClientDisconnectEventArgs(s, c));
                }
                if (s.ServiceHandler != null)
                {
                    tf.StartNew(() =>
                    {
                        try
                        {
                            s.ServiceHandler.SocketClosed(c);
                        }
                        catch (AggregateException ae)
                        {
                            ae.Handle((e) => { Logger.Instance.Error("套接字处理消息程序异常。", e); return true; });
                        }
                    });
                }
            }

            /// <summary>
            /// 客户接收。
            /// </summary>
            /// <param name="c"></param>
            public void Receive(SocketClient c)
            {
                if (s.Encoding != null)
                {
                    byte[] tmp = c.Message;
                    s.Encoding.Decode(c, ref tmp);
                    c.Message = tmp;
                }
                if (s.OnReceive != null)
                {
                    s.OnReceive(s, new ClientReceiveEventArgs(s, c));
                }
                if (s.ServiceHandler != null)
                {
                    tf.StartNew(() =>
                    {
                        try
                        {
                            s.ServiceHandler.SocketReceived(c, c.Message);
                        }
                        catch (AggregateException ae)
                        {
                            ae.Handle((e) => { Logger.Instance.Error("套接字处理消息程序异常。", e); return true; });
                        }
                    });
                }
            }

            /// <summary>
            /// 发送数据。
            /// </summary>
            /// <param name="c"><see cref="客户端"/></param>
            public void Send(SocketClient c, ref byte[] data, object stats)
            {
                if (s.Encoding != null)
                    s.Encoding.Encode(c, ref data);
                if (s.ServiceHandler != null)
                {
                    tf.StartNew(() =>
                    {
                        try
                        {
                            s.ServiceHandler.SocketSent(c, stats);
                        }
                        catch (AggregateException ae)
                        {
                            ae.Handle((e) => { Logger.Instance.Error("套接字处理消息程序异常。", e); return true; });
                        }
                    });
                }
            }

            /// <summary>
            /// 闲置时。
            /// </summary>
            /// <param name="c"></param>
            public void Idle(SocketClient c)
            {
                if (s.ServiceHandler != null)
                {
                    tf.StartNew(() =>
                    {
                        try
                        {
                            s.ServiceHandler.SocketIdle(c);
                        }
                        catch (AggregateException ae)
                        {
                            ae.Handle((e) => { Logger.Instance.Error("套接字处理消息程序异常。", e); return true; });
                        }
                    });
                }
            }

        }

        /// <summary>
        /// 客户端连接事件。
        /// </summary>
        public event EventHandler<ClientConnectionEventArgs> OnConnection;

        /// <summary>
        /// 客户端接收事件。
        /// </summary>
        public event EventHandler<ClientReceiveEventArgs> OnReceive;

        /// <summary>
        /// 客户端断开事件。
        /// </summary>
        public event EventHandler<ClientDisconnectEventArgs> OnDisconnect;

        private int port;
        private System.Net.Sockets.Socket service;
        private EventHandler handler;
        private Logger log = Logger.Instance;
        private bool isdispose = false;


        /// <summary>
        /// 用指定的端口初始化。
        /// </summary>
        /// <param name="port"><see cref="端口。"/></param>
        public SocketService(int port)
            : this(port, null)
        {

        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SocketService"/> class.
        /// </summary>
        /// <param name="port">The port.</param>
        /// <param name="handler">The handler.</param>
        public SocketService(int port, SocketServiceHandler handler)
            : this(port, null, handler)
        {

        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SocketService"/> class.
        /// </summary>
        /// <param name="port">The port.</param>
        /// <param name="encoding">The encoding.</param>
        /// <param name="handler">The handler.</param>
        public SocketService(int port, SocketEncoding encoding, SocketServiceHandler handler)
        {
            this.port = port;
            this.handler = new EventHandler(this);
            this.Encoding = encoding;
            this.ServiceHandler = handler;
            service = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }

        /// <summary>
        /// 套接字解码/编码器。
        /// </summary>
        public SocketEncoding Encoding { get; set; }

        /// <summary>
        /// 服务处理。
        /// </summary>
        public SocketServiceHandler ServiceHandler { get; set; }

        /// <summary>
        /// 获得处理引擎。
        /// </summary>
        public EventHandler HandlerEngine { get { return handler; } }

        /// <summary>
        /// 绑定端口。
        /// </summary>
        public void Bind()
        {
            service.ExclusiveAddressUse = true;
            service.Bind(new IPEndPoint(IPAddress.Any, port));
        }

        /// <summary>
        /// Listens this instance.
        /// </summary>
        public void Listen()
        {
            service.Listen(1000);
            service.BeginAccept(new AsyncCallback(EndAccept), null);
        }

        /// <summary>
        /// 监听请求。
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:丢失范围之前释放对象")]
        private void EndAccept(IAsyncResult result)
        {
            try
            {
                var socket = service.EndAccept(result);
                SocketClient.CreateInstance(this, socket);
            }
            catch (ObjectDisposedException)
            {
                return;
            }
            catch (SocketException se)
            {
                if (se.ErrorCode != 10052 && se.ErrorCode != 10054)
                {
                    log.Error("服务端请求错误:", se);
                }
            }
            catch (System.Exception ex)
            {
                log.Error("服务端请求错误:", ex);
            }
            service.BeginAccept(new AsyncCallback(EndAccept), null);
        }

        #region IDisposable 成员

        /// <summary>
        /// 执行与释放或重置非托管资源相关的应用程序定义的任务。
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
        protected virtual void Dispose(bool dispose)
        {
            if (isdispose)
            {
                return;
            }
            if (dispose)
            {
                service.Close();
                service.Dispose();
            }
            isdispose = true;
        }

        ~SocketService()
        {
            Dispose(false);
        }

        #endregion
    }



求优化。。求改进。。各种求。。 --------------------编程问答--------------------     /// <summary>
    /// TCP客户端类
    /// </summary>
    public class SocketClient : IDisposable
    {

        private System.Net.Sockets.Socket c;
        private SocketService server;
        private byte[] buf = new byte[4096];
        private int buflen = 0;
        private bool iscon = true;
        private TimerManager timer = null;
        private System.Net.IPEndPoint point;
        private Map<string, dynamic> dir = new Map<string, dynamic>();
        private Logger log = Logger.Instance;

        /// <summary>
        /// 添加属性到客户端。从此以后可以通过索引器索引。
        /// </summary>
        /// <param name="key"></param>
        /// <param name="obj"></param>
        public void AddAttribute(string key, dynamic obj)
        {
            dir.Add(key, obj);
        }

        /// <summary>
        /// 删除属性。
        /// </summary>
        /// <param name="key"></param>
        public void RemoveAttribute(string key)
        {
            dir.Remove(key);
        }

        /// <summary>
        /// 访问属性。
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public dynamic this[string key]
        {
            get
            {
                return dir[key];
            }
            set { dir[key] = value; }
        }

        /// <summary>
        /// 构造函数,构造新客户端。
        /// </summary>
        /// <param name="client"><see cref="客户端套接字。"/></param>
        private SocketClient(SocketService server, System.Net.Sockets.Socket client)
        {
            this.c = client;
            this.server = server;
            this.point = (System.Net.IPEndPoint)c.RemoteEndPoint;
            server.HandlerEngine.Connection(this);
            c.BeginReceive(buf, 0, buf.Length, SocketFlags.None, new AsyncCallback(EndReceive), null);
        }

        /// <summary>
        /// 创建实例。
        /// </summary>
        /// <param name="server"><see cref="服务端。"/></param>
        /// <param name="client"><see cref="客户端。"/></param>
        /// <returns></returns>
        public static SocketClient CreateInstance(SocketService server, System.Net.Sockets.Socket client)
        {
            return new SocketClient(server, client);
        }

        /// <summary>
        /// 收到的数据。
        /// </summary>
        public byte[] Message { get; set; }

        /// <summary>
        /// 远程地址。
        /// </summary>
        public System.Net.IPEndPoint RemoteIP
        {
            get
            {
                return point;
            }
        }

        private void EndReceive(IAsyncResult result)
        {
            try
            {
                buflen = c.EndReceive(result);
                if (buflen == 0)
                {
                    this.Dispose();
                    return;
                }
                using (System.IO.MemoryStream stream = new System.IO.MemoryStream(buf))//处理数据。
                {
                    byte[] tmp = new byte[buflen];
                    stream.Read(tmp, 0, tmp.Length);
                    Message = tmp;
                }
                server.HandlerEngine.Receive(this);
                timer.Reset();
                c.BeginReceive(buf, 0, buf.Length, SocketFlags.None, new AsyncCallback(EndReceive), null);
            }
            catch (SocketException se)
            {
                if (se.ErrorCode > 10054 && se.ErrorCode < 10052)
                {
                    log.Error("客户端请求接收错误:", se);
                }
                else
                {
                    this.Dispose();
                    return;
                }
            }
            catch (ObjectDisposedException)
            {
                return;//客户端已释放。
            }
            catch (Exception ex)
            {
                log.Error("客户端请求接收错误:", ex);
            }
        }

        /// <summary>
        /// Sets the idel.
        /// </summary>
        public void SetIdle(long milliseconds)
        {
            if (timer != null)
            {
                timer.Dispose();
            }
            timer = TimerManager.Registry(new Action(Idle), milliseconds);
        }

        /// <summary>
        /// Idles this instance.
        /// </summary>
        private void Idle()
        {
            server.HandlerEngine.Idle(this);
        }

        /// <summary>
        /// Writes the specified data.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns><see cref="已发送到 System.Net.Sockets.Socket 的字节数。"/></returns>
        [MethodImpl(MethodImplOptions.Synchronized)]//大概是静态方法只能一个线程执行。实例方法也只能一个线程执行。
        public int Write(byte[] data, object stats)
        {
            if (iscon)
            {
                timer.Reset();
                server.HandlerEngine.Send(this, ref data, stats);
                return c.Send(data);
            }
            throw new ObjectDisposedException(this.GetType().ToString());
        }

        /// <summary>
        /// Writes the specified data.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        public int Write(byte[] data)
        {
            return Write(data, null);
        }

        /// <summary>
        /// Writes the specified packet.
        /// </summary>
        /// <param name="packet">The packet.</param>
        /// <returns></returns>
        public int Write(MaplePacket packet)
        {
            return Write(packet.GetBytes(), packet);
        }

        #region IDisposable 成员

        /// <summary>
        /// 执行与释放或重置非托管资源相关的应用程序定义的任务。
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
        protected virtual void Dispose(bool dispose)
        {
            if (!iscon)
            {
                return;
            }
            if (dispose)
            {
                c.Disconnect(false);
                c.Close();
                if (timer != null)
                {
                    timer.Dispose();
                }
                Action<SocketClient> del = new Action<SocketClient>(server.HandlerEngine.Disconnect);
                del.BeginInvoke(this, null, null);
            }
            iscon = false;
        }

        ~SocketClient()
        {
            Dispose(false);
        }

        #endregion
    }
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,