• Echo Server,AsyncSocket,SocketAsyncEvent,SocketAsyncEventArgs,AsyncQueue


    
    namespace Test
    {
        using System;
        using System.Net;
        using System.Net.Sockets;
        using System.Text;
        using System.IO;
        using System.Threading;
        using Microshaoft;
        public class AsyncSocketAsyncDataQueueHandlerEchoServer
        {
            public static void StartListening()
            {
                //IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
                IPAddress ipAddress;
                IPAddress.TryParse("127.0.0.1", out ipAddress);
                IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 12021);
                Socket listener = new Socket
                                        (
                                            AddressFamily.InterNetwork
                                            , SocketType.Stream
                                            , ProtocolType.Tcp
                                        );
                listener.Bind(localEndPoint);
                Console.WriteLine("Listening ...");
                listener.Listen(10);
                int i = 0;
                while (true)
                {
                    int id = i++;
                    UserToken token = new UserToken();
                    token.ConnectionID = id;
                    Socket socket = listener.Accept();
                    Console.WriteLine("accept");
                    SocketAsyncDataHandler<UserToken> handler = new SocketAsyncDataHandler<UserToken>(socket, token);
                    handler.ReceiveDataBufferLength = 1;
                    handler.ID = id;
                    handler.DataReceivedCompletedAsync +=new SocketAsyncDataHandler<UserToken>.DataReceivedCompletedAsyncEventHandler(DataReceived_CompletedAsync);
                        
                    handler.StartReceiveData();
                }
            }
            static void DataReceived_CompletedAsync(SocketAsyncDataHandler<UserToken> sender, byte[] data)
            {
                string s = Encoding.ASCII.GetString(data);
                Console.WriteLine("[{0}],[{1}],[{2}]", sender.Token.ConnectionID, s, data.Length);
                sender.SendDataAsync(data);
            }
            public static int Main(String[] args)
            {
                StartListening();
                return 0;
            }
        }
        public class UserToken
        {
            public string UserID;
            public int ConnectionID;
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.Net;
        using System.Net.Sockets;
        using System.Text;
        using System.IO;
        using System.Threading;
        public class SocketAsyncDataHandler<T>
        {
            private AsyncQueue<byte[]> _sendQueue;
            private AsyncQueue<byte[]> _receiveQueue;
            private T _token;
            public T Token
            {
                get
                {
                    return _token;
                }
            }
            public SocketAsyncDataHandler(Socket socket, T token)
            {
                _sendQueue = new AsyncQueue<byte[]>();
                _sendQueue.OnDequeue += new AsyncQueue<byte[]>.QueueEventHandler(SendQueue_OnDequeue);
                //_sendQueue.OnQueueLog += new AsyncQueue<byte[]>.QueueLogEventHandler(Queue_OnQueueLog);
                _sendQueue.OnException += new AsyncQueue<byte[]>.ExceptionEventHandler(Queue_OnException);
                _sendQueue.MaxConcurrentThreadsCount = 1024;
                _receiveQueue = new AsyncQueue<byte[]>();
                _receiveQueue.OnDequeue += new AsyncQueue<byte[]>.QueueEventHandler(ReceiveQueue_OnDequeue);
                //_receiveQueue.OnQueueLog += new AsyncQueue<byte[]>.QueueLogEventHandler(Queue_OnQueueLog);
                _receiveQueue.OnException += new AsyncQueue<byte[]>.ExceptionEventHandler(Queue_OnException);
                _socket = socket;
                _token = token;
            }
            void Queue_OnException(Exception e)
            {
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine(e.Message);
                Console.ResetColor();
            }
            void Queue_OnQueueLog(string logMessage)
            {
                //            Console.WriteLine(logMessage);
            }
            void SendQueue_OnDequeue(byte[] element)
            {
                SendDataAsync(element);
            }
            void ReceiveQueue_OnDequeue(byte[] element)
            {
                if (DataReceivedCompletedAsync != null)
                {
                    DataReceivedCompletedAsync(this, element);
                }
            }
            public enum ExceptionHandleAction : int
            {
                Ignore
                ,
                ReThrow
                ,
                Abort
            }
            private Socket _socket;
            private int _id;
            public int ID
            {
                set
                {
                    _id = value;
                }
                get
                {
                    return _id;
                }
            }
            private int _receiveDataBufferLength  = 1024;
            public int ReceiveDataBufferLength
            {
                set
                {
                    _receiveDataBufferLength = value;
                }
            }
            public void SendData(byte[] data)
            {
                _socket.Send(data);
            }
            public void SendDataAsyncQueue(byte[] data)
            {
                _sendQueue.Enqueue(data);
            }
            public void SendDataAsync(byte[] data)
            {
                SocketAsyncEventArgs e = new SocketAsyncEventArgs();
                e.AcceptSocket = _socket;
                e.SetBuffer(data, 0, data.Length);
                _socket.SendAsync(e);
            }
            public delegate void DataReceivedCompletedAsyncEventHandler
                                                    (
                                                        SocketAsyncDataHandler<T> sender
                                                        , byte[] data
                                                    );
            public event DataReceivedCompletedAsyncEventHandler DataReceivedCompletedAsync;
            public delegate void ExceptionOccursEventHandler
                                                    (
                                                        SocketAsyncDataHandler<T> sender
                                                        , Exception exception
                                                        , ExceptionHandleAction action
                                                    );
            public ExceptionOccursEventHandler ExceptionOccurs;
            public void StartReceiveData()
            {
                SocketAsyncEventArgs e = new SocketAsyncEventArgs();
                e.AcceptSocket = _socket;
                e.Completed += new EventHandler<SocketAsyncEventArgs>(ReceivedData_Completed);
                byte[] buffer = new byte[_receiveDataBufferLength];
                e.SetBuffer(buffer, 0, buffer.Length);
                _socket.ReceiveAsync(e);
            }
            void ReceivedData_Completed(object sender, SocketAsyncEventArgs e)
            {
                int l = e.BytesTransferred;
                if (l > 0)
                {
                    byte[] data = new byte[l];
                    Buffer.BlockCopy(e.Buffer, 0, data, 0, data.Length);
                    _receiveQueue.Enqueue(data);
                }
                _socket.ReceiveAsync(e);
            }
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.IO;
        using System.Net.Sockets;
        public static class SocketDataHelper
        {
            public static void ReadDataToFixedLengthBytes
                                    (
                                        Socket socket,
                                        ref byte[] buffer
                                    )
            {
                int p = 0;
                int l = buffer.Length;
                while (p < l)
                {
                    int r = socket.Receive
                                        (
                                            buffer
                                            , p
                                            , l - p
                                            , SocketFlags.None
                                        );
                    p += r;
                }
            }
            public static byte[] ReadDataToFixedLengthBytes
                                        (
                                            int length,
                                            Socket socket
                                        )
            {
                int p = 0;
                byte[] data = new byte[length];
                while (p < length)
                {
                    int r = socket.Receive
                                        (
                                            data
                                            , p
                                            , length - p
                                            , SocketFlags.None
                                        );
                    p += r;
                }
                return data;
            }
            public static byte[] ReadDataToBytes
                                        (
                                            int length,
                                            Socket socket
                                        )
            {
                byte[] data = new byte[length];
                int r = 0;
                //SocketError error;
                r = socket.Receive
                                    (
                                        data
                                        , 0
                                        , length
                                        , SocketFlags.None
                    //, out error
                                    );
                //if (error != SocketError.Success)
                //{
                //    Console.WriteLine("socket error: {0}", Enum.GetName(typeof(SocketError), error));
                //    Thread.Sleep(100);
                //}
                if (r > 0)
                {
                    Array.Resize<byte>(ref data, r);
                }
                else
                {
                    data = null;
                }
                return data;
            }
            public static int ReadDataToBytes
                                    (
                                        Socket socket,
                                        ref byte[] buffer
                                    )
            {
                int r = 0;
                //SocketError error;
                int l = buffer.Length;
                r = socket.Receive
                                (
                                    buffer
                                    , 0
                                    , l
                                    , SocketFlags.None
                    //, out error
                                );
                //if (error != SocketError.Success)
                //{
                //    Console.WriteLine("socket error: {0}", Enum.GetName(typeof(SocketError), error));
                //    Thread.Sleep(100);
                //}
                if (r > 0)
                {
                    Array.Resize<byte>(ref buffer, r);
                }
                else
                {
                    buffer = null;
                }
                return r;
            }
        }
        public static class StreamDataHelper
        {
            private static byte[] ReadDataToBytes(Stream stream)
            {
                byte[] buffer = new byte[64 * 1024];
                MemoryStream ms = new MemoryStream();
                int r = 0;
                int l = 0;
                long position = -1;
                if (stream.CanSeek)
                {
                    position = stream.Position;
                    stream.Position = 0;
                }
                while (true)
                {
                    r = stream.Read(buffer, 0, buffer.Length);
                    if (r > 0)
                    {
                        l += r;
                        ms.Write(buffer, 0, r);
                    }
                    else
                    {
                        break;
                    }
                }
                byte[] bytes = new byte[l];
                ms.Position = 0;
                ms.Read(bytes, 0, (int)l);
                ms.Close();
                ms = null;
                if (position >= 0)
                {
                    stream.Position = position;
                }
                return bytes;
            }
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.Threading;
        using System.Collections.Generic;
        public class AsyncQueue<T>
                            where T : class
        {
            public delegate void QueueEventHandler(T element);
            public event QueueEventHandler OnDequeue;
            public delegate void QueueLogEventHandler(string logMessage);
            public event QueueLogEventHandler OnQueueLog;
            public delegate void ExceptionEventHandler(Exception exception);
            public event ExceptionEventHandler OnException;
            private Queue<T> _queue = new Queue<T>();
            private static object _SyncLockObject = new object();
            private int _concurrentThreadsCount = 0; //Microshaoft 用于控制并发线程数
            private volatile bool _queueRuning = false;
            private int _maxConcurrentThreadsCount = 1; //Microshaoft 允许并发出列处理线程数为 1
            public int MaxConcurrentThreadsCount
            {
                set
                {
                    _maxConcurrentThreadsCount = value;
                }
                get
                {
                    return _maxConcurrentThreadsCount;
                }
            }
            private long _EnqueueCount = 0; //入列计数器
            public long EnqueueCount
            {
                get
                {
                    return _EnqueueCount;
                }
            }
            private long _DequeueCount = 0; //出列计数器
            public long DequeueCount
            {
                get
                {
                    return _DequeueCount;
                }
            }
            //Microshaoft 服务启动后可立即开启新的线程调用此方法(死循环)
            private void QueueRun() //Microshaoft ThreadStart
            {
                if (!_queueRuning)
                {
                    _queueRuning = true;
                    lock (_SyncLockObject)
                    {
                        ThreadStart ts = new ThreadStart(QueueRunThreadProcess);
                        Thread t = new Thread(ts);
                        t.Name = "QueueRunThreadProcess";
                        t.Start();
                    }
                }
            }
            public int Count
            {
                get
                {
                    return _queue.Count;
                }
            }
            public int ConcurrentThreadsCount
            {
                get
                {
                    return _concurrentThreadsCount;
                }
            }
            private void QueueRunThreadProcess()
            {
                if (OnQueueLog != null)
                {
                    OnQueueLog
                        (
                            string.Format
                                    (
                                        "{0} Threads Count {1},Queue Count {2},Current Thread: {3}"
                                        , "Queue Runing Start ..."
                                        , _concurrentThreadsCount
                                        , _queue.Count
                                        , Thread.CurrentThread.Name
                                    )
                        );
                }
                while (_queue.Count > 0) //Microshaoft 死循环
                {
                    T element = null;
                    int threadID = -1;
                    lock (_SyncLockObject)
                    {
                        if (_concurrentThreadsCount < _maxConcurrentThreadsCount)
                        {
                            if (_queue.Count > 0)
                            {
                                Interlocked.Increment(ref _concurrentThreadsCount);
                                threadID = _concurrentThreadsCount;
                                if (_concurrentThreadsCount >= _maxConcurrentThreadsCount)
                                {
                                    if (OnQueueLog != null)
                                    {
                                        OnQueueLog
                                            (
                                                string.Format
                                                        (
                                                            "{0} Threads Count {1},Queue Count {2},Current Thread: {3}"
                                                            , "Threads is Full!"
                                                            , _concurrentThreadsCount
                                                            , _queue.Count
                                                            , Thread.CurrentThread.Name
                                                        )
                                            );
                                    }
                                }
                                if (OnQueueLog != null)
                                {
                                    OnQueueLog
                                        (
                                            string.Format
                                                    (
                                                        "{0} Threads Count {1},Queue Count {2},Current Thread: {3}"
                                                        , "Threads ++ !"
                                                        , _concurrentThreadsCount
                                                        , _queue.Count
                                                        , Thread.CurrentThread.Name
                                                    )
                                        );
                                }
                                element = _queue.Dequeue();
                            }
                        }
                    }
                    if (element != null)
                    {
                        //Microshaoft ThreadPool.QueueUserWorkelement(new WaitCallback(OnDequeueThreadProcess), element);
                        ThreadProcessState tps = new ThreadProcessState();
                        tps.element = element;
                        tps.Sender = this;
                        Thread t = new Thread(new ThreadStart(tps.ThreadProcess));
                        t.Name = string.Format("ConcurrentThread[{0}]", threadID);
                        t.Start();
                    }
                }
                _queueRuning = false;
                if (OnQueueLog != null)
                {
                    OnQueueLog
                        (
                            string.Format
                                (
                                    "{0} Threads Count {1},Queue Count {2},Current Thread: {3}"
                                    , "Queue Runing Stopped!"
                                    , _concurrentThreadsCount
                                    , _queue.Count
                                    , Thread.CurrentThread.Name
                                )
                        );
                }
            }
            public void Enqueue(T element)
            {
                try
                {
                    lock (_SyncLockObject) //还算并发吗?
                    {
                        _queue.Enqueue(element);
                    }
                    Interlocked.Increment(ref _EnqueueCount);
                }
                catch (Exception e)
                {
                    if (OnException != null)
                    {
                        OnException(e);
                    }
                }
                if (!_queueRuning)
                {
                    QueueRun();
                }
            }
            private void OnDequeueThreadProcess(T element)
            {
                try
                {
                    if (OnDequeue != null)
                    {
                        OnDequeue(element);
                    }
                    Interlocked.Increment(ref _DequeueCount);
                    DequeueProcess();
                }
                catch (Exception e)
                {
                    if (OnException != null)
                    {
                        OnException(e);
                    }
                }
                finally
                {
                    Interlocked.Decrement(ref _concurrentThreadsCount);
                    if (_concurrentThreadsCount == 0)
                    {
                        if (OnQueueLog != null)
                        {
                            OnQueueLog
                                (
                                    string.Format
                                            (
                                                "{0} Threads Count {1},Queue Count {2},Current Thread: {3}"
                                                , "All Threads Finished!"
                                                , _concurrentThreadsCount
                                                , _queue.Count
                                                , Thread.CurrentThread.Name
                                            )
                                );
                        }
                    }
                    if (OnQueueLog != null)
                    {
                        OnQueueLog
                            (
                                string.Format
                                        (
                                            "{0} Threads Count {1},Queue Count {2},Current Thread: {3}"
                                            , "Threads -- !"
                                            , _concurrentThreadsCount
                                            , _queue.Count
                                            , Thread.CurrentThread.Name
                                        )
                            );
                    }
                }
            }
            private void DequeueProcess()
            {
                while (_queue.Count > 0)
                {
                    T element = null;
                    lock (_SyncLockObject)
                    {
                        if (_queue.Count > 0)
                        {
                            element = _queue.Dequeue();
                        }
                    }
                    if (element != null)
                    {
                        if (OnDequeue != null)
                        {
                            OnDequeue(element);
                        }
                        Interlocked.Increment(ref _DequeueCount);
                    }
                }
            }
            private class ThreadProcessState
            {
                private AsyncQueue<T> _sender;
                public AsyncQueue<T> Sender
                {
                    get
                    {
                        return _sender;
                    }
                    set
                    {
                        _sender = value;
                    }
                }
                private T _element;
                public T element
                {
                    get
                    {
                        return _element;
                    }
                    set
                    {
                        _element = value;
                    }
                }
                public void ThreadProcess()
                {
                    _sender.OnDequeueThreadProcess(_element);
                }
            }
        }
    }
    
    
  • 相关阅读:
    【转】VS2010中 C++创建DLL图解
    [转]error: 'retainCount' is unavailable: not available in automatic reference counting mode
    [转]关于NSAutoreleasePool' is unavailable: not available in automatic reference counting mode的解决方法
    【转】 Tomcat v7.0 Server at localhost was unable to start within 45
    【转】Server Tomcat v7.0 Server at localhost was unable to start within 45 seconds. If
    【转】SVN管理多个项目版本库
    【转】eclipse安装SVN插件的两种方法
    【转】MYSQL启用日志,和查看日志
    【转】Repository has not been enabled to accept revision propchanges
    【转】SVN库的迁移
  • 原文地址:https://www.cnblogs.com/Microshaoft/p/1583355.html
Copyright © 2020-2023  润新知