SocketAsyncDataHandler SocketAsyncEventArgs echo server


//Client.cs
namespace Client
{
    using System;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;
    using Microshaoft;
    class Class1
    {
        static void Main(string[] args)
        {
            var ipa = IPAddress.Parse("127.0.0.1");
            var socket = new Socket
                                (
                                    AddressFamily.InterNetwork
                                    , SocketType.Stream
                                    , ProtocolType.Tcp
                                );
            var ipep = new IPEndPoint(ipa, 18180);
            socket.Connect(ipep);
            var handler = new SocketAsyncDataHandler<string>
                                                        (
                                                            socket
                                                            , 1
                                                        );
            var sendEncoding = Encoding.Default;
            var receiveEncoding = Encoding.UTF8;
            receiveEncoding = Encoding.Default;
            var decoder = receiveEncoding.GetDecoder();
            handler.StartReceiveData
                            (
                                1024 * 8
                                , (x, y, z) =>
                                {
                                    var l = decoder.GetCharCount(y, 0, y.Length);
                                    var chars = new char[l];
                                    decoder.GetChars(y, 0, y.Length, chars, 0, false);
                                    var s = new string(chars);
                                    Console.Write(s);
                                    return true;
                                }
                            );
            string input = string.Empty;
            while ((input = Console.ReadLine()) != "q")
            {
                try
                {
                    var buffer = sendEncoding.GetBytes(input);
                    Array.ForEach
                            (
                                buffer
                                , (x) =>
                                {
                                    handler.SendDataSync(new[] { x });
                                    Thread.Sleep(100);
                                }
                            );
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
            }
        }
    }
}
//===========================================================================================
//Share.cs
namespace Microshaoft
{
    using System;
    using System.Net;
    using System.Net.Sockets;
    public class SocketAsyncDataHandler<T>
    {
        private Socket _socket;
        public Socket WorkingSocket
        {
            get
            {
                return _socket;
            }
        }
        public int ReceiveDataBufferLength
        {
            get;
            private set;
        }
        public T ConnectionToken
        {
            get;
            set;
        }
        public IPAddress RemoteIPAddress
        {
            get
            {
                return ((IPEndPoint)_socket.RemoteEndPoint).Address;
            }
        }
        public IPAddress LocalIPAddress
        {
            get
            {
                return ((IPEndPoint)_socket.LocalEndPoint).Address;
            }
        }
        public int SocketID
        {
            get;
            private set;
        }
        public SocketAsyncDataHandler
                            (
                                Socket socket
                                , int socketID
                            )
        {
            _socket = socket;
            _sendSocketAsyncEventArgs = new SocketAsyncEventArgs();
            SocketID = socketID;
        }
        private SocketAsyncEventArgs _sendSocketAsyncEventArgs;
        public int HeaderBytesLength
        {
            get;
            private set;
        }
        public int HeaderBytesOffset
        {
            get;
            private set;
        }
        public int HeaderBytesCount
        {
            get;
            private set;
        }
        private bool _isStartedReceiveData = false;
        private bool _isHeader = true;
        public bool StartReceiveWholeDataPackets
                            (
                                int receiveBufferLength
                                , int headerBytesLength
                                , int headerBytesOffset
                                , int headerBytesCount
                                , Func
                                    <
                                        SocketAsyncDataHandler<T>
                                        , byte[]
                                        , SocketAsyncEventArgs
                                        , bool
                                    > onOneWholeDataPacketReceivedProcessFunc
                                , Func
                                    <
                                        SocketAsyncDataHandler<T>
                                        , byte[]
                                        , SocketAsyncEventArgs
                                        , bool
                                    > onDataPacketReceivedErrorProcessFunc = null
                                , Action
                                    <
                                        SocketAsyncDataHandler<T>
                                        , bool
                                    > onAfterDestoryWorkingSocketProcessAction = null
                            )
        {
            if (!_isStartedReceiveData)
            {
                HeaderBytesLength = headerBytesLength;
                HeaderBytesOffset = headerBytesOffset;
                HeaderBytesCount = headerBytesCount;
                var saeaReceive = new SocketAsyncEventArgs();
                int bodyLength = 0;
                saeaReceive.Completed += new EventHandler<SocketAsyncEventArgs>
                                (
                                    (sender, e) =>
                                    {
                                        var socket = sender as Socket;
                                        if (e.BytesTransferred >= 0)
                                        {
                                            byte[] buffer = e.Buffer;
                                            int r = e.BytesTransferred;
                                            int p = e.Offset;
                                            int l = e.Count;
                                            if (r < l)
                                            {
                                                p += r;
                                                e.SetBuffer(p, l - r);
                                            }
                                            else if (r == l)
                                            {
                                                if (_isHeader)
                                                {
                                                    byte[] data = new byte[headerBytesCount];
                                                    Buffer.BlockCopy
                                                                (
                                                                    buffer
                                                                    , HeaderBytesOffset
                                                                    , data
                                                                    , 0
                                                                    , data.Length
                                                                );
                                                    byte[] intBytes = new byte[4];
                                                    l = (intBytes.Length < HeaderBytesCount ? intBytes.Length : HeaderBytesCount);
                                                    Buffer.BlockCopy
                                                                (
                                                                    data
                                                                    , 0
                                                                    , intBytes
                                                                    , 0
                                                                    , l
                                                                );
                                                    //Array.Reverse(intBytes);
                                                    bodyLength = BitConverter.ToInt32(intBytes, 0);
                                                    p += r;
                                                    e.SetBuffer(p, bodyLength);
                                                    Console.WriteLine(bodyLength);
                                                    _isHeader = false;
                                                }
                                                else
                                                {
                                                    byte[] data = new byte[bodyLength + HeaderBytesLength];
                                                    bodyLength = 0;
                                                    Buffer.BlockCopy(buffer, 0, data, 0, data.Length);
                                                    _isHeader = true;
                                                    e.SetBuffer(0, HeaderBytesLength);
                                                    if (onOneWholeDataPacketReceivedProcessFunc != null)
                                                    {
                                                        onOneWholeDataPacketReceivedProcessFunc
                                                                                        (
                                                                                            this
                                                                                            , data
                                                                                            , e
                                                                                        );
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                if (onDataPacketReceivedErrorProcessFunc != null)
                                                {
                                                    byte[] data = new byte[p + r + HeaderBytesLength];
                                                    Buffer.BlockCopy(buffer, 0, data, 0, data.Length);
                                                    bool b = onDataPacketReceivedErrorProcessFunc
                                                                                    (
                                                                                        this
                                                                                        , data
                                                                                        , e
                                                                                    );
                                                    if (b)
                                                    {
                                                        bool i = DestoryWorkingSocket();
                                                        if (onAfterDestoryWorkingSocketProcessAction != null)
                                                        {
                                                            onAfterDestoryWorkingSocketProcessAction(this, i);
                                                        }
                                                    }
                                                    else
                                                    {
                                                        _isHeader = true;
                                                        e.SetBuffer(0, HeaderBytesLength);
                                                    }
                                                }
                                            }
                                        }
                                        try
                                        {
                                            socket.ReceiveAsync(e);
                                        }
                                        catch (Exception exception)
                                        {
                                            Console.WriteLine(exception.ToString());
                                            DestoryWorkingSocket();
                                        }
                                    }
                                );
                ReceiveDataBufferLength = receiveBufferLength;
                saeaReceive.SetBuffer
                                (
                                    new byte[ReceiveDataBufferLength]
                                    , 0
                                    , HeaderBytesLength
                                );
                _socket.ReceiveAsync(saeaReceive);
                _isStartedReceiveData = true;
            }
            return _isStartedReceiveData;
        }
        public bool DestoryWorkingSocket()
        {
            bool r = false;
            try
            {
                if (_socket.Connected)
                {
                    _socket.Disconnect(false);
                }
                _socket.Shutdown(SocketShutdown.Both);
                _socket.Close();
                _socket.Dispose();
                _socket = null;
                r = true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                //r = false;
            }
            return r;
        }
        public bool StartReceiveData
                            (
                                int receiveBufferLength
                                , Func
                                    <
                                        SocketAsyncDataHandler<T>
                                        , byte[]
                                        , SocketAsyncEventArgs
                                        , bool
                                    > onDataReceivedProcessFunc
                            )
        {
            if (!_isStartedReceiveData)
            {
                var saeaReceive = new SocketAsyncEventArgs();
                saeaReceive.Completed += new EventHandler<SocketAsyncEventArgs>
                                                (
                                                    (sender, e) =>
                                                    {
                                                        var socket = sender as Socket;
                                                        int l = e.BytesTransferred;
                                                        if (l > 0)
                                                        {
                                                            byte[] data = new byte[l];
                                                            var buffer = e.Buffer;
                                                            Buffer.BlockCopy(buffer, 0, data, 0, data.Length);
                                                            if (onDataReceivedProcessFunc != null)
                                                            {
                                                                onDataReceivedProcessFunc(this, data, e);
                                                            }
                                                        }
                                                        try
                                                        {
                                                            socket.ReceiveAsync(e);
                                                        }
                                                        catch (Exception exception)
                                                        {
                                                            Console.WriteLine(exception.ToString());
                                                        }
                                                    }
                                                );
                ReceiveDataBufferLength = receiveBufferLength;
                saeaReceive.SetBuffer
                                (
                                    new byte[ReceiveDataBufferLength]
                                    , 0
                                    , ReceiveDataBufferLength
                                );
                _socket.ReceiveAsync(saeaReceive);
                _isStartedReceiveData = true;
            }
            return _isStartedReceiveData;
        }
        private object _sendSyncLockObject = new object();
        public int SendDataSync(byte[] data)
        {
            lock (_sendSyncLockObject)
            {
                return _socket.Send(data);
            }
        }
    }
}
//=======================================================================================================
//Server.cs
namespace Server
{
    using System;
    using System.Net;
    using System.Net.Sockets;
    using Microshaoft;
    class EchoServer<T>
    {
        //Socket _socketListener;
        private Action<SocketAsyncDataHandler<T>, byte[]> _onReceivedDataProcessAction;
        public EchoServer
                    (
                        IPEndPoint localPoint
                        , Action
                            <
                                SocketAsyncDataHandler<T>
                                , byte[]
                            >
                            onReceivedDataProcessAction
                    )
        {
            _onReceivedDataProcessAction = onReceivedDataProcessAction;
            var listener = new Socket
                            (
                                localPoint.AddressFamily
                                , SocketType.Stream
                                , ProtocolType.Tcp
                            );
            listener.Bind(localPoint);
            listener.Listen(5);
            AcceptSocketAsyc(listener);
        }
        private void AcceptSocketAsyc(Socket listener)
        {
            var acceptSocketAsyncEventArgs = new SocketAsyncEventArgs();
            acceptSocketAsyncEventArgs.Completed += acceptSocketAsyncEventArgs_AcceptOneCompleted;
            listener.AcceptAsync(acceptSocketAsyncEventArgs);
        }
        private int _socketID = 0;
        void acceptSocketAsyncEventArgs_AcceptOneCompleted(object sender, SocketAsyncEventArgs e)
        {
            e.Completed -= acceptSocketAsyncEventArgs_AcceptOneCompleted;
            var client = e.AcceptSocket;
            var listener = sender as Socket;
            AcceptSocketAsyc(listener);
            var handler = new SocketAsyncDataHandler<T>
                                                        (
                                                            client
                                                            , _socketID++
                                                        );
            handler.StartReceiveData
                        (
                            1024
                            , (x, y, z) =>
                            {
                                //var s = Encoding.UTF8.GetString(y);
                                ////Console.WriteLine("SocketID: {1}{0}Length: {2}{0}Data: {2}", "\r\n", x.SocketID, y.Length ,s);
                                //Console.Write(s);
                                if (_onReceivedDataProcessAction != null)
                                {
                                    _onReceivedDataProcessAction(x, y);
                                }
                                return true;
                            }
                        );
            //handler.StartReceiveWholeDataPackets
            //                    (
            //                        1024 * 1024
            //                        , 2
            //                        , 0
            //                        , 2
            //                        , (x, y, z) =>
            //                        {
            //                            var s = Encoding.UTF8.GetString(y);
            //                            //Console.WriteLine("SocketID: {1}{0}Length: {2}{0}Data: {2}", "\r\n", x.SocketID, y.Length ,s);
            //                            Console.Write(s);
            //                            return true;
            //                        }
            //                    );
        }
    }
}
namespace Server
{
    using System;
    using System.Net;
    using System.Text;
    public class Class1
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        //[STAThread]
        static void Main(string[] args)
        {
            IPAddress ipa;
            IPAddress.TryParse("127.0.0.1", out ipa);
            var receiveEncoding = Encoding.Default;
            var sendEncoding = Encoding.UTF8;
            sendEncoding = Encoding.Default;
            var decoder = receiveEncoding.GetDecoder();
            var es = new EchoServer<string>
                            (
                                new IPEndPoint(ipa, 18180)
                                , (x, y) =>
                                {
                                    var l = decoder.GetCharCount(y, 0, y.Length);
                                    var chars = new char[l];
                                    decoder.GetChars(y, 0, y.Length, chars, 0, false);
                                    var s = new string(chars);
                                    Console.Write(s);
                                    //s = string.Format("Echo: {0}{1}{0}", "\r\n", s);
                                    var buffer = sendEncoding.GetBytes(s);
                                    x.SendDataSync(buffer);
                                }
                            );
            Console.WriteLine("Hello World");
            Console.WriteLine(Environment.Version.ToString());
            Console.ReadLine();
        }
    }
}

原文地址:https://www.cnblogs.com/Microshaoft/p/2629139.html