Common.TcpLibTcpClientT

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 TcpClientT : Common.TcpLib.ITcpClient
    {
        public Socket _clientSocket;
        private string _serverIp;
        private int _port;
        private int _bufferSize = 1024;
        private Thread _thread;
        private ManualResetEvent sendDone = new ManualResetEvent(false);

        private bool _disposed = false;
        private bool _debug = 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 TcpClientT(string serverIp, int port)
        {
            this._serverIp = serverIp;
            this._port = port;
        }

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

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

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

        private void ReceiveThread()
        {
            try
            {
                _Bgz_ConnectionState stx = new _Bgz_ConnectionState(_clientSocket);
                while (true)
                {
                    try
                    {
                        stx._buffer = new byte[0];
                        stx._count = 0;
                        stx._getonceall = false;
                        _clientSocket.Receive(stx._buffer);

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

                        OnReceiveBeginEvent(stx);

                        stx._count = 0;
                        stx._dataStream.SetLength(0);
                        stx._dataStream.Position = 0;
                        if (stx._getonceall)
                        {
                            stx._buffer = new byte[_clientSocket.Available];
                            int ret = _clientSocket.Receive(stx._buffer, 0, stx._buffer.Length, SocketFlags.None);
                            if (ret > 0)
                            {
                                stx._dataStream.Write(stx._buffer, 0, stx._buffer.Length);
                                stx._count++;
                                OnReceiveingEvent(stx);
                            }
                        }
                        else
                        {
                            while (_clientSocket.Available > 0)
                            {
                                if (_clientSocket.Available > _bufferSize)
                                    stx._buffer = new byte[_bufferSize];
                                else
                                    stx._buffer = new byte[_clientSocket.Available];
                                int ret = _clientSocket.Receive(stx._buffer, 0, stx._buffer.Length, SocketFlags.None);
                                if (ret > 0)
                                {
                                    stx._dataStream.Write(stx._buffer, 0, stx._buffer.Length);
                                    stx._count++;
                                    OnReceiveingEvent(stx);
                                }
                            }
                        }
                        OnReceiveEndEvent(stx);
                    }
                    catch (Exception ex)
                    {
                        Stop();
                        if (Debug)
                        {
                            OnErrorEvent(ErrorType.Catch, "ReceiveThread.1 Error![Message]:\r\n" + ex.Message + "[StackTrace]:\r\n" + ex.StackTrace + "\r\n", stx);
                        }
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                Stop();
                if (Debug)
                {
                    OnErrorEvent(ErrorType.Catch, "ReceiveThread.2 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)
            {
                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
            {
                this._clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                this._clientSocket.Connect(new IPEndPoint(IPAddress.Parse(_serverIp), _port));

                _Bgz_ConnectionState stx = new _Bgz_ConnectionState(_clientSocket);
                OnConnectEvent(stx);

                _sotpMessage = false;
                _stopLock = new object();
                _thread = new Thread(new ThreadStart(ReceiveThread));
                _thread.Start();
            }
            catch (Exception ex)
            {
                if (Debug)
                {
                    OnErrorEvent(ErrorType.Catch, "Connect Error![Message]:\r\n" + ex.Message + "[StackTrace]:\r\n" + ex.StackTrace + "\r\n", null);
                }
                Stop();
            }
        }

        public void Stop()
        {
            try
            {
                if (_clientSocket != null)
                    if (this._clientSocket.Connected) this._clientSocket.Close();
                _thread.Abort();
                _thread = null;
                lock (_stopLock)
                {
                    if (!_sotpMessage)
                    {
                        OnErrorEvent(ErrorType.DisAccept, "关闭与服务器的连接!", 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);
                }
            }
        }

        public void Send(byte[] msg)
        {
            try
            {
                if (_clientSocket.Connected == false)
                {
                    throw (new Exception("没有连接成功不可以发送信息!"));
                }
                _clientSocket.Send(msg);
            }
            catch (Exception ex)
            {
                OnErrorEvent(ErrorType.Catch, ex.Message, 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)
            {
                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)
            {
                if (Debug)
                {
                    OnErrorEvent(ErrorType.Catch, "Send Error![Message]:\r\n" + ex.Message + "[StackTrace]:\r\n" + ex.StackTrace + "\r\n", null);
                }
            }
        }

        #endregion
    }

}

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