Common.TcpLibTcpClientY

using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Runtime.InteropServices;
using System.IO;

namespace Common.TcpLib
{

    /// <summary>
    /// 异步Socket处理客户端
    /// </summary>
    public class TcpClientY : Common.TcpLib.ITcpClient
    {
        public Socket _clientSocket;
        private string _serverIp;
        private int _port;
        private int _bufferSize = 1024;

        private bool _disposed = false;
        private bool _debug = false;
        private ManualResetEvent sendDone = new ManualResetEvent(false);
        private object _stopLock = new object();
        private bool _sotpMessage = false;

        #region define delegates
        /// <summary>
        /// 连接上服务器后的事件处理
        /// </summary>
        public _Bgz_OnConnectEventDelegate FOnConnectEventDelegate;

        /// <summary>
        /// 接收服务端发来的数据事件处理
        /// </summary>
        public _Bgz_OnReceiveBeginEventDelegate FOnReceiveBeginEventDelegate;

        /// <summary>
        /// 接收服务端发来的数据事件处理
        /// </summary>
        public _Bgz_OnReceiveingEventDelegate FOnReceiveingEventDelegate;

        /// <summary>
        /// 接收服务端发来的数据事件处理
        /// </summary>
        public _Bgz_OnReceiveEndEventDelegate FOnReceiveEndEventDelegate;

        /// <summary>
        /// 报错信息处理
        /// </summary>
        public _Bgz_OnErrorEventDelegate FOnErrorEventDelegate;
        #endregion

        #region Event
        private void OnConnectEvent(_Bgz_ConnectionState state)
        {
            if (FOnConnectEventDelegate != null) FOnConnectEventDelegate(state);
        }
        private void OnReceiveBeginEvent(_Bgz_ConnectionState state)
        {
            if (FOnReceiveBeginEventDelegate != null) FOnReceiveBeginEventDelegate(state);
        }
        private void OnReceiveingEvent(_Bgz_ConnectionState state)
        {
            if (FOnReceiveingEventDelegate != null) FOnReceiveingEventDelegate(state);
        }
        private void OnReceiveEndEvent(_Bgz_ConnectionState state)
        {
            if (FOnReceiveEndEventDelegate != null) FOnReceiveEndEventDelegate(state);
        }
        private void OnErrorEvent(ErrorType errortype, string msg, _Bgz_ConnectionState state)
        {
            if (FOnErrorEventDelegate != null) FOnErrorEventDelegate(errortype, msg, state);
        }
        #endregion

        #region property

        public int BufferSize
        {
            get
            {
                return _bufferSize;
            }
        }

        public bool Debug
        {
            get
            {
                return _debug;
            }
            set
            {
                _debug = value;
            }
        }
        #endregion

        #region Constructor and Destructor
        public TcpClientY(string serverIp, int port)
        {
            this._serverIp = serverIp;
            this._port = port;
        }

        public TcpClientY(string serverIp, int port, int bufferSize)
        {
            this._serverIp = serverIp;
            this._port = port;
            this._bufferSize = bufferSize;
        }

        ~TcpClientY()
        {
            if (!_disposed)
            {
                Stop();
            }
        }
        #endregion

        #region Private Methods
        private void Dispose()
        {
            if (!_disposed)
            {
                Stop();
                GC.Collect();
                GC.WaitForPendingFinalizers();
                this.FOnConnectEventDelegate = null;
                this.FOnErrorEventDelegate = null;
                this.FOnReceiveBeginEventDelegate = null;
                this.FOnReceiveEndEventDelegate = null;
                this.FOnReceiveingEventDelegate = null;
                _disposed = true;
            }
        }

        private void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
                _Bgz_ConnectionState stx = ar.AsyncState as _Bgz_ConnectionState;

                OnReceiveBeginEvent(stx);

                stx._conn.EndReceive(ar);

                if (stx._conn.Available == 0)
                {
                    Stop();
                    return;
                }

                #region receive
                lock (ar)
                {
                    stx._count = 0;
                    stx._dataStream.SetLength(0);
                    stx._dataStream.Position = 0;
                    if (stx._getonceall)
                    {
                        stx._buffer = new byte[stx.AvailableData];
                        int ret = stx.Read(stx._buffer, 0, stx._buffer.Length);
                        if (ret > 0)
                        {
                            stx._dataStream.Write(stx._buffer, 0, stx._buffer.Length);
                            stx._count++;
                            OnReceiveingEvent(stx);
                        }
                    }
                    else
                    {
                        while (stx.AvailableData > 0)
                        {
                            if (stx.AvailableData > _bufferSize)
                                stx._buffer = new byte[_bufferSize];
                            else
                                stx._buffer = new byte[stx.AvailableData];
                            int ret = stx.Read(stx._buffer, 0, stx._buffer.Length);
                            if (ret > 0)
                            {
                                stx._dataStream.Write(stx._buffer, 0, stx._buffer.Length);
                                stx._count++;
                                OnReceiveingEvent(stx);
                            }
                        }
                    }
                }
                #endregion

                OnReceiveEndEvent(stx);

                if (stx.Connected)
                    stx._conn.BeginReceive(stx._buffer, 0, 0, SocketFlags.None, new AsyncCallback(ReceiveCallback), stx);
            }
            catch (Exception ex)
            {
                Stop();
                if (Debug)
                {
                    OnErrorEvent(ErrorType.Catch, "ReceiveCallback Error![Message]:\r\n" + ex.Message + "[StackTrace]:\r\n" + ex.StackTrace + "\r\n", null);
                }
            }
        }

        private void SendCallback(IAsyncResult ar)
        {
            try
            {
                Socket client = (Socket)ar.AsyncState;
                int bytesSent = client.EndSend(ar);
            }
            catch (Exception ex)
            {
                Stop();
                if (Debug)
                {
                    OnErrorEvent(ErrorType.Catch, "Send Error![Message]:\r\n" + ex.Message + "[StackTrace]:\r\n" + ex.StackTrace + "\r\n", null);
                }
            }
            finally
            {
                sendDone.Set();
            }
        }
        #endregion

        #region Public Methods

        public void Connect()
        {
            try
            {
                _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                _clientSocket.Connect(new IPEndPoint(IPAddress.Parse(_serverIp), _port));

                _Bgz_ConnectionState stx = new _Bgz_ConnectionState();
                stx._conn = this._clientSocket;
                OnConnectEvent(stx);
                _stopLock = new object();
                _sotpMessage = false;

                _clientSocket.BeginReceive(stx._buffer, 0, 0, SocketFlags.None, new AsyncCallback(ReceiveCallback), stx);
            }
            catch (Exception ex)
            {
                OnErrorEvent(ErrorType.Catch, "连接到远程服务器" + _serverIp + ":" + _port.ToString() + "失败!\r\n" + ex.Message, null);
            }
        }

        public void Send(byte[] msg)
        {
            try
            {
                if (_clientSocket.Connected)
                    _clientSocket.Send(msg);
                else
                {
                    _Bgz_ConnectionState stx = new _Bgz_ConnectionState();
                    stx._conn = this._clientSocket;
                    stx._buffer = msg;
                    OnErrorEvent(ErrorType.DisConnect, "未与服务器建立链接,导致发送数据失败!", stx);
                }
            }
            catch (Exception ex)
            {
                Stop();
                if (Debug)
                {
                    OnErrorEvent(ErrorType.Catch, "Send Error![Message]:\r\n" + ex.Message + "[StackTrace]:\r\n" + ex.StackTrace + "\r\n", null);
                }
            }
        }

        public void SendAsync(byte[] msg)
        {
            try
            {
                if (_clientSocket.Connected == false)
                {
                    throw (new Exception("没有连接客户端不可以发送信息!"));
                }

                byte[] buffer;
                int count = msg.Length;
                int cur = 0;
                while (count > 0)
                {
                    if (count > this._bufferSize)
                        buffer = new byte[_bufferSize];
                    else
                        buffer = new byte[count];

                    for (int i = 0; i < buffer.Length; i++)
                    {
                        buffer[i] = msg[cur + i];
                    }
                    count -= buffer.Length;

                    cur += buffer.Length;

                    _clientSocket.BeginSend(buffer, 0, buffer.Length, 0, new AsyncCallback(SendCallback), _clientSocket);
                    sendDone.WaitOne();
                }
            }
            catch (Exception ex)
            {
                Stop();
                if (Debug)
                {
                    OnErrorEvent(ErrorType.Catch, "Send Error![Message]:\r\n" + ex.Message + "[StackTrace]:\r\n" + ex.StackTrace + "\r\n", null);
                }
            }
        }

        public void SendAsync(Stream Astream)
        {
            try
            {
                if (_clientSocket.Connected == false)
                {
                    throw (new Exception("没有连接客户端不可以发送信息!"));
                }

                byte[] buffer;
                long count = Astream.Length;
                while (count > 0)
                {
                    if (count > this._bufferSize)
                        buffer = new byte[this._bufferSize];
                    else
                        buffer = new byte[count];

                    Astream.Read(buffer, 0, buffer.Length);
                    count -= buffer.Length;
                    _clientSocket.BeginSend(buffer, 0, buffer.Length, 0, new AsyncCallback(SendCallback), _clientSocket);
                    sendDone.WaitOne();
                }
            }
            catch (Exception ex)
            {
                Stop();
                if (Debug)
                {
                    OnErrorEvent(ErrorType.Catch, "Send Error![Message]:\r\n" + ex.Message + "[StackTrace]:\r\n" + ex.StackTrace + "\r\n", null);
                }
            }
        }

        public void Stop()
        {
            try
            {
                if (_clientSocket != null)
                {
                    if (_clientSocket.Connected)
                    {
                        _clientSocket.Shutdown(SocketShutdown.Both);
                        _clientSocket.Disconnect(false);
                    }
                    _clientSocket.Close();
                }
                lock (_stopLock)
                {

                    if (!_sotpMessage)
                    {
                        OnErrorEvent(ErrorType.DisConnect, "关闭了与服务器的连接!", null);
                        _sotpMessage = true;
                    }
                }
            }
            catch (Exception ex)
            {
                if (Debug)
                {
                    OnErrorEvent(ErrorType.Catch, "Stop Error![Message]:\r\n" + ex.Message + "[StackTrace]:\r\n" + ex.StackTrace + "\r\n", null);
                }
            }
        }

        #endregion

    }

}

posted @ 2007-11-01 21:45  我想去长安  阅读(265)  评论(0编辑  收藏  举报