c# Socket 的应用

---------------AjaxBaseSocket.cs-------------- 

public abstract class AjaxBaseSocket : IDisposable
    {
        protected Socket _socket;
        protected AjaxBaseSocket(IPEndPoint ipAddress)
        {
            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }

        protected abstract void Close();

        #region IDisposable Members

        public void Dispose()
        {
            Close();
            GC.SuppressFinalize(this);
        }

        #endregion
    }

------AjaxMessage.cs----------------

   public  sealed  class AjaxMessage:EventArgs 
    {

        private  int _key;
        private string _body;
        public  AjaxMessage(int key,string content):base()
        {
            _key = key;
            _body = content;
        }
        public int Key
        {
            get { return _key; }
        }
        public string Body
        {
            get { return _body; }
        }
    }

---------------------AjaxMessageHelper.cs-----------------

     public sealed  class AjaxMessageHelper
    {
        public static readonly byte[] MessageSeperate = new byte[]{159,187,169,175,
            141,184,17,73,
            182,159,124,238,
            167,208,193,196};

public sealed class Crc16
    {
        const ushort polynomial = 0xA001;
        ushort[] table = new ushort[]    {
               0,94,188,226,97,63,221,131,194,156,126,32,163,253,31,65,
               157,195,33,127,252,162,64,30, 95,1,227,189,62,96,130,220,
               35,125,159,193,66,28,254,160,225,191,93,3,128,222,60,98,
               190,224,2,92,223,129,99,61,124,34,192,158,29,67,161,255,
               70,24,250,164,39,121,155,197,132,218,56,102,229,187,89,7,            
               219,133,103,57,186,228,6,88,25,71,165,251,120,38,196,154,
               101,59,217,135,4,90,184,230,167,249,27,69,198,152,122,36,                        
               248,166,68,26,153,199,37,123,58,100,134,216,91,5,231,185,            
               140,210,48,110,237,179,81,15,78,16,242,172,47,113,147,205,
               17,79,173,243,112,46,204,146,211,141,111,49,178,236,14,80,
               175,241,19,77,206,144,114,44,109,51,209,143,12,82,176,238,
               50,108,142,208,83,13,239,177,240,174,76,18,145,207,45,115,
               202,148,118,40,171,245,23,73,8,86,180,234,105,55,213,139,
               87,9,235,181,54,104,138,212,149,203, 41,119,244,170,72,22,
               233,183,85,11,136,214,52,106,43,117,151,201,74,20,246,168,
               116,42,200,150,21,75,169,247,182,232,10,84,215,137,107,53
              };

        public ushort ComputeChecksum(byte[] bytes)
        {
            ushort crc = 0;
            for (int i = 0; i < bytes.Length; i++)
            {
                byte index = (byte)(crc ^ bytes[i]);
                crc = (ushort)((crc >> 8) ^ table[index]);
            }
            return crc;
        }

        public byte[] ComputeChecksumBytes(byte[] bytes)
        {
            ushort crc = ComputeChecksum(bytes);
            return new byte[] { (byte)(crc >> 8), (byte)(crc & 0x00ff) };
        }

        public Crc16()
        {
           

        }
    }

--------------------取之网上,对不对我也不知道,不过,同样的数据,就算是算法错误,得到的结果也应该一样,

 

        static  Crc16 crc;

        private AjaxMessageHelper()
        {
            
        }
        static AjaxMessageHelper()
        {

            crc = new Crc16();
        
           
        }
        public static byte[] ToByte(AjaxMessage message)
        {
            string txt = message.Body;
            byte[] body = System.Text.Encoding.Unicode.GetBytes(message.Body);
            ushort checkSum = crc.ComputeChecksum(body);
            byte[] checkBytes=BitConverter.GetBytes(checkSum ); 
            byte[] lenData = BitConverter.GetBytes(body.Length);
            byte[] data = new byte[26 + body.Length];
            //Copy  Sepearte
            Array.Copy(MessageSeperate, data, 16);

            byte[] key = BitConverter.GetBytes(message.Key);
            //Copy key
            for (int i = 16; i < 20; i++)
            {
                data[i] = key[i - 16];
            }
            ///Copy  BodyLenght
            for (int i = 20; i < 24; i++)
            {
                data[i] = lenData[i - 20];
            }
            ///copy CheckByte
            for (int i = 24; i < 26; i++)
            {
                data[i] = checkBytes[i - 24];
            }
            //Copy data
            Array.Copy(body, 0, data, 26, body.Length);
            return data;
        }
        public static AjaxMessage ToMessage(byte[] data)
        {
            AjaxMessage ajMsg = null;

            int key = BitConverter.ToInt32(data, 16);
            int len = BitConverter.ToInt32(data, 20);
        

         

            string msg = System.Text.Encoding.Unicode.GetString(data, 26, len);
            ajMsg = new AjaxMessage(key, msg);
            return ajMsg;
        }
        /// <summary>
        /// 是不是一个完整的数据包
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static bool CompletedPacket(byte[] data)
        {
            if (data.Length < 26)
                return false;
            for (int i = 0; i < 16; i++)
            {
                if (data[i] != MessageSeperate[i])
                {
                    Console.WriteLine("MessageSeperate");
                    return false;
                }
            }
            int len = BitConverter.ToInt32(data, 20);
            if (len + 26 != data.Length)
                return false ;
            ushort check = BitConverter.ToUInt16(data, 24);

            byte[] tmp = new byte[len];
            Array.Copy(data, 26, tmp, 0, len);

            ushort c2 = crc.ComputeChecksum(tmp);
            if (check != c2)
            {
                Console.WriteLine("Check");
                return false;
            }
            if (data.Length == len + 26)
            {
                Console.WriteLine("Len");
                return true;
            }
            else
            {
                return false;
            }
        }
        public static int BoundaryIndex(byte[] data, int startPos)
        {
            if (data.Length < AjaxMessageHelper.MessageSeperate.Length)
                return -1;
            int bIndex = 0;
            int bLen = AjaxMessageHelper.MessageSeperate.Length;

            int iPos = startPos;
            int lc = data.Length;
            bool bEind = false;
            while ((iPos < lc) && (bEind == false))
            {
                if (data[iPos] == AjaxMessageHelper.MessageSeperate[bIndex])
                {
                    bIndex++;
                }
                else
                {
                    bIndex = 0;
                }
                if (bIndex == bLen)
                {
                    bEind = true;
                }
                iPos++;
            }
            if (bEind)
            {
                return iPos - 16;
            }
            else
            {
                return -1;
            }


        }

      
    }

AjaxServerSocket.cs

public delegate void  AjaxMessageArrivedEventHandle(WorkerSocket w,AjaxMessage msg);
    public delegate void AjaxSocketClientConnectedEventHandle(WorkerSocket w);
    public  class AjaxServerSocket:AjaxBaseSocket
    {
        static ManualResetEvent mr = new ManualResetEvent(true);

   

        public event AjaxMessageArrivedEventHandle AjaxMessageArrived;
        public event AjaxSocketClientConnectedEventHandle AjaxClientConnected;
        public event AjaxMessageArrivedEventHandle AjaxMessageSendCompleted;
  
        public AjaxServerSocket(IPEndPoint ipAddress)
            : base(ipAddress)
        {
            _socket.Bind(ipAddress);
        }

        private void accepteCallback(IAsyncResult ar)
        {
            Socket server = ar.AsyncState as Socket;
            Socket handler = server.EndAccept(ar);
            mr.Set();
            
            WorkerSocket ws = new WorkerSocket(handler);
            if (AjaxClientConnected != null)
            {
                AjaxClientConnected(ws);
            }
            ws.AjaxMessageParseOk += new EventHandler<AjaxMessage>(ws_AjaxMessageParseOk);
            ws.AjaxMessageSendOk += new EventHandler<AjaxMessage>(ws_AjaxMessageSendOk);
            ws.Read();
      
        }

        void ws_AjaxMessageSendOk(object sender, AjaxMessage e)
        {
            if (AjaxMessageSendCompleted != null)
            {
                AjaxMessageSendCompleted((WorkerSocket)sender, e);
            }
        }

        void ws_AjaxMessageParseOk(object sender, AjaxMessage e)
        {
            if (AjaxMessageArrived != null)
            {
                WorkerSocket ws = sender as WorkerSocket;
                AjaxMessageArrived(ws, e);
            }
           
        }
     
        public void Run()
        {
            _socket.Listen(1000);
            while (true)
            {
                mr.Reset();
                Console.WriteLine("Waiting for connecting...");
                _socket.BeginAccept(new AsyncCallback(accepteCallback), _socket);
                mr.WaitOne();
            }
        }

      

     

        protected override void Close()
        {
            _socket.Shutdown(SocketShutdown.Both);
            _socket.Close(30000);
        }

}

----------------------WorkerSocket.cs--------------------

 public  class WorkerSocket:IDisposable
    {
        private ManualResetEvent readHandle = new ManualResetEvent(true);
        private ManualResetEvent sendHandle = new ManualResetEvent(true);

        private ManualResetEvent mr = new ManualResetEvent(true);
        private ManualResetEvent mw = new ManualResetEvent(true);
        public event EventHandler<AjaxMessage> AjaxMessageParseOk;
        public event EventHandler<AjaxMessage> AjaxMessageSendOk;
        public event EventHandler ReadCompleted;
        private Socket worker;
        private MemoryStream ms;
        private byte[] buffer;
       
        public WorkerSocket(Socket socket)
        {
            worker = socket;
            ms = new MemoryStream();
            buffer = new byte[1024];
        }

        public EventWaitHandle ReadHandle
        {
            get
            {
                return readHandle;
            }
        }

        public EventWaitHandle SendHandle
        {
            get
            {
                return sendHandle;
            }
        }

        private void Add(byte[] readData)
        {
            mr.WaitOne();
            mw.Reset();
            try
            {

                mr.Reset();
                try
                {
                    ms.Write(readData, 0, readData.Length);

                    byte[] data = ms.ToArray();

                    int st = AjaxMessageHelper.BoundaryIndex(data, 0);
                    if (st == -1)
                    {
                        ms.Write(readData, 0, readData.Length);
                    }
                    else
                    {

                        int nextStart = AjaxMessageHelper.BoundaryIndex(data, st + 26);

                        AjaxMessage msg = null;
                        while (nextStart != -1)
                        {
                            byte[] tmp = new byte[nextStart - st];
                            Array.Copy(data, st, tmp, 0, nextStart - st);

                            if (AjaxMessageHelper.CompletedPacket(tmp))
                            {
                                msg = AjaxMessageHelper.ToMessage(tmp);

                            }
                            else
                            {
                                msg = new AjaxMessage(0, "DataPacketError");
                            }
                            if (AjaxMessageParseOk != null)
                            {
                                AjaxMessageParseOk(this, msg);
                            }
                            st = nextStart;
                            nextStart = AjaxMessageHelper.BoundaryIndex(data, st + 26);

                        }
                        int len = data.Length;
                        int leftLen = len - st;
                        byte[] left = new byte[leftLen];
                        Array.Copy(data, st, left, 0, leftLen);
                        if (AjaxMessageHelper.CompletedPacket(left))
                        {
                            msg = AjaxMessageHelper.ToMessage(left);
                            if (AjaxMessageParseOk != null)
                            {
                                AjaxMessageParseOk(this, msg);
                            }
                            ms.Seek(0, SeekOrigin.Begin);
                            ms.SetLength(0);
                        }
                        else
                        {
                            ms.Seek(0, SeekOrigin.Begin);
                            ms.Write(left, 0, leftLen);
                            ms.SetLength(leftLen);
                        }
                    }
                }
                finally
                {
                    mr.Set();
                }
            }
            finally
            {
                mw.Set();
            }
        }

        private void receiveCallback(IAsyncResult ar)
        {
           
            int read =worker.EndReceive(ar);
            if (read != 0)
            {
                byte[] tmp = new byte[read];
                Array.Copy(this.buffer, tmp, read);
                this.Add(tmp);
                worker.BeginReceive(buffer, 0, 1024, SocketFlags.None, new AsyncCallback(receiveCallback), null);
            }
            else
            {
                if (this.ReadCompleted != null)
                {
                    this.ReadCompleted(this, EventArgs.Empty);
                }
                readHandle.Set();
            }
        }


        public  void Read()
        {
            readHandle.Reset();
            worker.BeginReceive(buffer, 0, 1024, SocketFlags.None, new AsyncCallback(receiveCallback), null);
 
        }
   
        private void sendCallback(IAsyncResult ar)
        {
            SendState s = ar.AsyncState as SendState;
            int i = worker.EndSend(ar);
            int gcd = s.Len / 1024;
            int left = s.Len % 1024;
            s.Order = s.Order + 1;
            if (s.Order < gcd)
            {
                worker.BeginSend(s.Data, s.Order * 1024, 1024, SocketFlags.None, new AsyncCallback(sendCallback), s);
            }
            else if (s.Order == gcd)
            {
                worker.BeginSend(s.Data, s.Order * 1024, left, SocketFlags.None, new AsyncCallback(sendCallback), s);
            }
            else
            {
                sendHandle.Set();
                if (AjaxMessageSendOk != null)
                {
                    AjaxMessageSendOk(this, s.Msg);
                }
            }
           
        }
      
        public void SendMessage(AjaxMessage msg)
        {
            byte[] d = AjaxMessageHelper.ToByte(msg);
            sendHandle.Reset();
            SendState s =  new SendState(d, 0,msg);
            AsyncCallback cb = new AsyncCallback(sendCallback);
            if (d.Length <= 1024)
            {
                worker.BeginSend(d, 0, d.Length, SocketFlags.None, cb, s);

            }
            else
            {
                worker.BeginSend(d, 0, 1024, SocketFlags.None, cb, s);
            }

        }

    
        internal class SendState
        {
      
            public byte[] Data;
            private int len;
            private int order;

            private AjaxMessage _msg;

            public AjaxMessage Msg
            {
                get
                {
                    return _msg;
                }
            }
            public int Len
            {
                get
                {
                    return len;
                }
            }
            public int Order
            {
                get
                {
                    return order;
                }
                set
                {
                    order = value;
                }
            }
      

            public SendState(byte[] data, int orders,AjaxMessage msg)
            {
                Data = data;
             
                len = data.Length;
                order = orders;
                _msg = msg;

            
            }
        }


        public Socket Worker
        {
            get
            {
                return worker;
            }
        }
        #region IDisposable Members

        public void Dispose()
        {
            if (ms != null)
            {
                ms.Close();
            }
            if (worker != null)
            {
                worker.Shutdown(SocketShutdown.Both);
                worker.Close();
            }
        }

        #endregion
        
       

    }

 

--------------------------Server---------------------------------

class Program
    {
        static List<EventWaitHandle> lstMr = new List<EventWaitHandle>();
        static List<EventWaitHandle> lstMs = new List<EventWaitHandle>();
        static void Main(string[] args)
        {

                IPEndPoint ipend = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5959);
                using (AjaxSocket.AjaxServerSocket s = new AjaxSocket.AjaxServerSocket(ipend))
                {
                    s.AjaxClientConnected += new AjaxSocket.AjaxSocketClientConnectedEventHandle(s_AjaxClientConnected);
                    s.AjaxMessageArrived += new AjaxSocket.AjaxMessageArrivedEventHandle(s_AjaxMessageArrived);
                    s.Run();
                    EventWaitHandle.WaitAll(lstMr.ToArray());
                   
                }
        
        }

        static void s_AjaxMessageArrived(AjaxSocket.WorkerSocket w, AjaxSocket.AjaxMessage msg)
        {
            Console.WriteLine("{0}:{1}", msg.Key, msg.Body);

        }

        static void s_AjaxClientConnected(AjaxSocket.WorkerSocket w)
        {
            lstMr.Add(w.ReadHandle);
            lstMs.Add(w.SendHandle);
        }

       

   
    }

-------------------------Client----------------------------

  static void Main(string[] args)
        {
            string[] mes = new string[]{
                "SOGOU推广服务",
                "美国伟哥给你强大性能力!(图)性爱延时30分钟,三倍的硬度让她高潮迭起,美国原产伟哥,全球1.4亿人见证,原产正品,假一罚十",
                "九酷免费电影--中国大而全的免费电影网站九酷免费电影网提供最新的,最全的电影在线观看,免费电影下载,欧美,港台,内地,日韩,恐怖等.. ",
                "30天阴茎增大8cm低价促销阴茎增大胶囊全球畅销的男根增大产品,回馈新老客户 超值赠品 任选.给您带来男根增大3英寸的奇迹! 两性治疗.. ",
                "永华电池,永放光华!我们是专业生产碱性电池及碱性电池机械制造的一个综合性企业,产品质量通过了ISO9001:2000国际.. ",
                 "引言CRC的全称为Cyclic Redundancy Check,中文名称为循环冗余校验。它是一类重要的线性分组码编码和解码方法简单,检错和纠错能力强,在通信领域广泛地用于实现差错控制。实际上,除数据通信外,CRC在其它很多领域也是大有用武之地的。例如我们读软盘上的文件,以及解压一个ZIP文件时,偶尔会碰到“Bad CRC”错误,由此它在数据存储方面的应用可略见一斑。差错控制理论是在代数理论基础上建立起来的。这里我们着眼于介绍CRC的算法与实现,对原理只能捎带说明一下。若需要进一步了解线性码、分组码、循环码、纠错编码等方面的原理,可以阅读有关资料。利用CRC进行检错的过程可简单描述为:在发送端根据要传送的k位二进制码序列,以一定的规则产生一个校验用的r位监督码(CRC码),附在原始信息后边,构成一个新的二进制码序列数共k+r位,然后发送出去。在接收端,根据信息码和CRC码之间所遵循的规则进行检验,以确定传送中是否出错。这个规则,在差错控制理论中称为引言CRC的全称为Cyclic Redundancy Check,中文名称为循环冗余校验。它是一类重要的线性分组码,编码和解码方法简单,检错和纠错能力强,在通信领域广泛地用于实现差错控制。实际上,除数据通信外,CRC在其它很多领域也是大有用武之地的。例如我们读软盘上的文件,以及解压一个ZIP文件时,偶尔会碰到“Bad CRC”错误,由此它在数据存储方面的应用可略见一斑。差错控制理论是在代数理论基础上建立起来的。这里我们着眼于介绍CRC的算法与实现,对原理只能捎带说明一下。若需要进一步了解线性码、分组码、循环码、纠错编码等方面的原理,可以阅读有关资料。利用CRC进行检错的过程可简单描述为:在发送端根据要传送的k位二进制码序中文名称为循环冗余校验。它是一类重要的线性分组码编码和解码方法简单,检错和纠错能力强,在通信领域广泛地用于实现差错控制。实际上,除数据通信外,CRC在其它很多领域也是大有用武之地的。例如我们读软盘上的文件,以及解压一个ZIP文件时,偶尔会碰到“Bad CRC”错误,由此它在数据存储方面的应用可略见一斑。差错控制理论是在代数理论基础上建立起来的。这里我们着眼于介绍CRC的算法与实现,对原理只能捎带说明一下。若需要进一步了解线性码、分组码、循环码、纠错编码等方面的原理,可以阅读有关资料。利用CRC进行检错的过程可简单描述为:在发送端根据要传送的k位二进制码序列,以一定的规则产生一个校验用的r位监督码(CRC码),附在原始信息后边,构成一个新的二进制码序列数共k+r位,然后发送出去。在接收端,根据信息码和CRC码之间所遵循的规则进行检验,以确定传送中是否出错。这个规则,在差错控制理论中称为引言CRC的全称为Cyclic Redundancy Check,中文名称为循环冗余校验。它是一类重要的线性分组码,编码和解码方法简单,检错和纠错能力强,在通信领域广泛地用于实现差错控制。实际上,除数据通信外,CRC在其它很多领域也是大有用武之地的。例如我们读软盘上的文件,以及解压一个ZIP文件时,偶尔会碰到“Bad CRC”错误,由此它在数据存储方面的应用可略见一斑。差错控制理论是在代数理论基础上建立起来的。这里我们着眼于介绍CRC的算法与实现,对原理只能捎带说明一下。若需要进一步了解线性码、分组码、循环码、纠错编码等方面的原理,可以阅读有关资料。利用CRC进行检错的过程可简单描述为:在发送端根据要传送的k位二进制码序",
             };
            IPEndPoint ipend = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5959);
            Random rd=new Random();
            using (AjaxSocket.AjaxClientSocket cs = new AjaxSocket.AjaxClientSocket(ipend))
            {
                cs.SendCompleted += new EventHandler(cs_SendCompleted);
                int i = 1;
                foreach (string s in mes)
                {
                    AjaxSocket.AjaxMessage msg = new AjaxSocket.AjaxMessage(16 + i, "Message: " + s);
                    cs.SendMessage(msg);
                    i++;
                    System.Threading.Thread.Sleep(1000);
                  
                }
                System.Threading.Thread.Sleep(1000);
            }
        }

        static void cs_SendCompleted(object sender, EventArgs e)
        {
            Console.WriteLine("SendOk");
        }

}

-------------------------------------------OVER------------------------

 

VS2008  +  Win Vista Sp1

posted on 2008-05-19 21:14  老代哥哥  阅读(260)  评论(0编辑  收藏  举报

导航