Socket Async Receive Data to LinkedList Buffer (echo server)


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.StartReceiveData();
                new Thread
                        (
                            delegate()
                            {
                                StartReadData(handler);
                            }
                        ).Start();
            }
        }
        static void StartReadData(SocketAsyncDataHandler<UserToken> handler)
        {
            while (true)
            {
                string s = Console.ReadLine();
                int l = 4;
                int.TryParse(s, out l);
                if (l == 0)
                {
                    l = 4095;
                }
                byte[] buffer = new byte[l];
                int r = handler.ReadData(buffer);
                if (r < l)
                {
                    Array.Resize<byte>(ref buffer, r);
                }
                s = Encoding.ASCII.GetString(buffer);
                //Console.WriteLine("[{0}],[{1}],[{2}]", sender.Token.ConnectionID, s, data.Length);
                Console.WriteLine("[{0}]",s);
            }
        }
        static void handler_AsyncDataReceivedCompleted(SocketAsyncDataHandler<UserToken> sender, byte[] data)
        {
            //throw new NotImplementedException();
            string s = Encoding.ASCII.GetString(data);
            //Console.WriteLine("[{0}],[{1}],[{2}]", sender.Token.ConnectionID, s, data.Length);
            Console.Write(s);
            //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.Sockets;
    using System.Collections.Generic;
    public class SocketAsyncDataHandler<T>
    {
        private LinkedList<byte[]> _receivedDataLinkedList = new LinkedList<byte[]>();
        public delegate void DataEventHandler(SocketAsyncDataHandler<T> sender, byte[] data);
        public event DataEventHandler AsyncDataReceivedCompleted;
        private object _syncLockObject = new object();
        private T _token;
        public T Token
        {
            get
            {
                return _token;
            }
        }
        public SocketAsyncDataHandler(Socket socket, T token)
        {
            _socket = socket;
            _token = token;
        }
        public int ReadData(byte[] buffer)
        {
            int l = buffer.Length;
            int p = 0;
            while (p < l)
            {
                if (_receivedDataLinkedList.Count <= 0)
                {
                    break;
                }
                if (_receivedDataLinkedList.First == null)
                {
                    break;
                }
                byte[] data = _receivedDataLinkedList.First.Value;
                
                int size = ((l - p) > data.Length ? data.Length : (l - p));
                if ((l - p) >= data.Length)
                {
                    lock (_syncLockObject)
                    {
                        _receivedDataLinkedList.RemoveFirst();
                    }
                }
                Buffer.BlockCopy(data, 0, buffer, p, size);
                if ((l - p) < data.Length)
                {
                    byte[] newData = new byte[size];
                    Buffer.BlockCopy(data, data.Length - size, newData, 0, newData.Length);
                    _receivedDataLinkedList.First.Value = newData;
                }
                p += size;
            }
            return p;
        }
        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 SendDataAsync(byte[] data)
        {
            SocketAsyncEventArgs e = new SocketAsyncEventArgs();
            e.AcceptSocket = _socket;
            e.SetBuffer(data, 0, data.Length);
            _socket.SendAsync(e);
        }
        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);
        }
        private 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);
                lock (_syncLockObject)
                {
                    _receivedDataLinkedList.AddLast(data);
                }
                if (AsyncDataReceivedCompleted != null)
                {
                    AsyncDataReceivedCompleted(this, data); 
                }
                
            }
            _socket.ReceiveAsync(e);
        }
    }
}

posted @ 2010-10-16 23:54  于斯人也  阅读(514)  评论(0编辑  收藏  举报