zoukankan      html  css  js  c++  java
  • Common.TcpLibTcpClientWIOCP

    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>
        /// 仿IOCP Socket处理客户端
        /// </summary>
        public class TcpClientWIOCP : 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 connectDone = new ManualResetEvent(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 TcpClientWIOCP(string serverIp, int port)
            {
                this._serverIp = serverIp;
                this._port = port;
            }

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

            ~TcpClientWIOCP()
            {
                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 ConnectCallback(IAsyncResult ar)
            {
                try
                {
                    Socket client = (Socket)ar.AsyncState;
                    client.EndConnect(ar);

                    _Bgz_ConnectionState stx = new _Bgz_ConnectionState(client);
                    OnConnectEvent(stx);
                }
                catch (Exception ex)
                {
                    Stop();
                    if (Debug)
                    {
                        OnErrorEvent(ErrorType.Catch, "ConnectCallback Error![Message]:\r\n" + ex.Message + "[StackTrace]:\r\n" + ex.StackTrace + "\r\n", null);
                    }
                }
                finally
                {
                    connectDone.Set();
                }
            }

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

                    OnReceiveBeginEvent(stx);

                    handler.EndReceive(ar);

                    if (handler.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[handler.Available];
                            int ret = handler.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 (handler.Available > 0)
                            {
                                if (handler.Available > _bufferSize)
                                    stx._buffer = new byte[_bufferSize];
                                else
                                    stx._buffer = new byte[handler.Available];
                                int ret = handler.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);
                                }
                            }
                        }
                    }
                    #endregion

                    OnReceiveEndEvent(stx);

                    if (handler.Connected)
                        handler.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
                {
                    this._clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                    connectDone.Reset();
                    this._clientSocket.BeginConnect(new IPEndPoint(IPAddress.Parse(_serverIp), _port), new AsyncCallback(ConnectCallback), this._clientSocket);
                    connectDone.WaitOne();
                    _stopLock = new object();
                    _sotpMessage = false;

                    _Bgz_ConnectionState stx = new _Bgz_ConnectionState(this._clientSocket);

                    _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

        }

    }

  • 相关阅读:
    Docker之路-docker架构
    Docker之路-认识docker
    Docker之路-版本选择及安装
    Golang理解-集合
    大话算法-动态规划算法
    运维职责
    Golang理解-匿名结构体
    DotNetty项目基本了解和介绍
    变量声明在循环体内还是循环体外的争论
    SqlServer与MySql语法比较
  • 原文地址:https://www.cnblogs.com/bigmouthz/p/946191.html
Copyright © 2011-2022 走看看