Baal的专栏

魔力小宝蓝---IBM---I BELIEVE MONEY

用户操作
[即时聊天] [发私信] [加为好友]
baalID:soft_fair
57444次访问,排名2022,好友1人,关注者1人。
soft_fair的文章
原创 47 篇
翻译 4 篇
转载 61 篇
评论 8 篇
baal的公告
新势力海报网
新势力论坛
男人找乐子的网站
伟大的操作系统linux

Google


[ 新浪ViVi ] [ Poco网摘 ] [ 365KEY ] [ 博采 ] [ 亿友响享 ] [ 你摘 ] [ YouNote ] [ 天极网摘 ] [ 和讯网摘 ]

最近评论
frankrade:关注一下
lz有点不地道:http://blogs.msdn.com/tess/archive/2008/02/20/net-debugging-demos-lab-3-memory-review.aspx

原创翻译吗?原?!!!
钱先生:去 http://www.6128.cn/entry.htm 看看,,不过也是大部分打不开的,,
钱先生:文章不错,但是不难发现里面有些句子可能漏了些关键的词汇,苦了那些菜鸟。
haha:ok
文章分类
收藏
    相册
    SEO
    SEO(RSS)
    SEO探索
    好东西
    baal自己的东西
    google相关的一个blog
    微软官方安全摘要
    民兵的家园
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 socket 多线程 异步编程收藏

    新一篇: 为MMC编写服务器控制管理单元。插件方式 (MMC3.0 , installutil ,c#,KB907265,Enterprise Library) | 旧一篇: GC是如何工作的,不同的代的大小是多少

    最近写了个socket的多线程 异步编程的组件。因为以前都是写写asp.net 的东西,这个多线程 和异步 还有 socket 都没有搞过,所以自我感觉写的不是很好。线程安全上不知道会不会有问题。今天把代码发上来,希望可以有高人指点里面的错误。同时,和大家共享一下我的代码。

    server端

    app.config:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <appSettings>
        <add key="ServerIpAddress" value="10.13.12.15"/>
        <add key="ServerSocketPort" value="399"/>
        <add key="ServerSocketBufferSize" value="100"/>
      </appSettings>
    </configuration>

     

    Program.cs

     

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading;
    using System.Diagnostics;
    using MySocket;
    using System.Windows.Forms;
    
    namespace ServerConsole
    {
        class Program
        {
            public static void Main()
            {
                Server srv = ServerFactory.CreateInstance();
                srv.AfterReceivedData += new EventHandler(srv_ReceivedDate);
                //srv.BeforeSendData += new BeforeSendDataEventHandler(srv_BeforeSendData);
    
                
               
    
                try
                {
    
                    //srv.mythread = new Thread(new ThreadStart(srv.BeginListen));
    
                    //srv.mythread.Start();
    
    
                    srv.OnStart();
                    
                    Console.WriteLine("press enter key to end");
                    Console.ReadLine();
    
                }
    
                catch (System.Exception er)
                {
    
                    MessageBox.Show(er.Message, "完成", MessageBoxButtons.OK, MessageBoxIcon.Stop);
    
                }
                finally
                {
    
                    //srv.mythread.Abort();//中止线程 
                    srv.OnStop();
                }
    
                Thread.Sleep(1500);
    
            }
    
            static byte[] srv_BeforeSendData(object sender, BeforeSendDataEventArgs e)
            {
                string Igot = "I got: " + Encoding.Default.GetString(e.Data);
    
                return Encoding.Default.GetBytes(Igot);
            }
    
            static void srv_ReceivedDate(object sender, AfterReceivedDataEventArgs e)
            {
                Trace.WriteLine("Program Console got: "+Encoding.Default.GetString(e.Data));
            }
        }
    }
    

     EventArgs.cs

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace MySocket
    {
        public class AfterReceivedDataEventArgs : EventArgs
        {
            byte[] data;
            public byte[] Data { get { return data; } set { data = value; } }
    
            public AfterReceivedDataEventArgs(byte[] data)
            {
                this.data = data;
            }
    
        }
    
        public class BeforeSendDataEventArgs : EventArgs
        {
            byte[] data;
            public byte[] Data { get { return data; } set { data = value; } }
    
            public BeforeSendDataEventArgs(byte[] data)
            {
                this.data = data;
            }
    
        }
    
    
        public class SessionTerminateEventArgs : EventArgs
        {
            Session session;
            public Session Session { get { return session; } set { session = value; } }
    
            public SessionTerminateEventArgs(Session session)
            {
                this.session = session;
            }
    
        }
    
        public delegate byte[] BeforeSendDataEventHandler(object sender,BeforeSendDataEventArgs e);
    
    }
    

    Server.cs:

    //服务端: 
    
    using System.Net; 
    
    using System.Net.Sockets; 
    
    using System.Text; 
    
    using System.Threading;
    using System;
    using System.Windows.Forms;
    using System.Collections.Generic;
    using System.Diagnostics;
    
    
    namespace MySocket
    {
        /// 
        /// Socket Server.Listening incoming.
        /// 
        public class Server : IDisposable
        {
    
            Socket listener;
            Dictionary clientItems; //session list.
            private int _currentSessionNumber = 0;
            private object _syncObject = new object();
            private bool disposed = false;
    
            private string strIpAddress;
            private int port;
            private int bufferSize;
            private IPEndPoint ipEndpoint;
            private int backlog;
    
            public Dictionary Sessions { get { return clientItems; } }
    
            //接收事件 
            public event EventHandler AfterReceivedData;
    
            public event BeforeSendDataEventHandler BeforeSendData;
    
            public string StrIpAddress { get { return strIpAddress; } set { strIpAddress = value; } }
    
            public int Port { get { return port; } set { port = value; } }
    
            public int BufferSize { get { return bufferSize; } set { bufferSize = value; } }
    
            public int Backlog { get { return backlog; } set { backlog = value; } }
    
    
            /// 
            /// 初始化一个socket server 实例,要指定ip地址,端口号,缓存字节的大小
            /// 
            /// ip地址
            /// 端口号
            /// 预留缓存的大小
            public Server(string strIpAddress, int port,int bufferSize)
            {
                this.strIpAddress = strIpAddress;
                this.port = port;
                this.bufferSize = bufferSize;
    
    
                clientItems = new Dictionary();
    
                ipEndpoint = new IPEndPoint(IPAddress.Parse(strIpAddress), port);
    
                listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    
                Trace.WriteLine("ipEndpoint  :" + ipEndpoint.ToString());
    
                
            }
            /// 
            /// OnStart,start the server to listen
            /// 
            public void OnStart()
            {
                Trace.WriteLine("BeginListen...");
    
                try
                {
                    listener.Bind(ipEndpoint);
    
                    listener.Listen(backlog);
    
                    listener.BeginAccept(new AsyncCallback(OnConnectRequest), listener);
                }
    
                catch (SocketException ex)
                {
    
                    Trace.WriteLine("Error:" + ex.ToString());
    
                }
            }
    
            /// 
            /// OnConnectRequest,create new session.
            /// 
            /// 
            private void OnConnectRequest(IAsyncResult ar)
            {
                Socket listener = (Socket)ar.AsyncState;
    
                lock (_syncObject)
                {
                    if (false == disposed)
                    {//if disposed ,do nothing.otherwise,do something.
                        
                        //create session ,store it in the list.
                        CreateNewSession(listener.EndAccept(ar));
                        
                        listener.BeginAccept(new AsyncCallback(OnConnectRequest), listener);
                    }
                    
                }
            }
    
            /// 
            /// CreateNewSession,init the session, delegate.
            /// 
            /// new socket that will deal the connection,ie receive the data, send data.
            private void CreateNewSession(Socket socket)
            {
                Trace.WriteLine(string.Format("Client {0}, connected", socket.RemoteEndPoint));
    
                int clientId = Interlocked.Increment(ref _currentSessionNumber);
                Session sc = new Session(clientId, socket,this.bufferSize);
                sc.AfterReceivedData += new EventHandler(session_AfterReceivedData);
                sc.SessionTerminated += new EventHandler(session_SessionTerminated);
    
                // hook the session's BeforeSendData to the server's BeforeSendData
                // so in the server code ,you can deal it by your self.
                if(BeforeSendData!=null)
                    sc.BeforeSendData += BeforeSendData;
    
                //session begin to work.
                sc.BeginReceiveData();
    
                lock (_syncObject)
                {
                    //add the session to the list.
                    clientItems.Add(sc.ID, sc);
                }
    
            }
    
            /// 
            /// session_SessionTerminated,remove it from list, close the session. dedelegate tht event.
            /// 
            /// 
            /// 
            void session_SessionTerminated(object sender, SessionTerminateEventArgs e)
            {
                lock (_syncObject)
                {
                    clientItems.Remove(e.Session.ID);
                }
                e.Session.Close();
                e.Session.AfterReceivedData -= session_AfterReceivedData;
                e.Session.SessionTerminated -= session_SessionTerminated;
                e.Session.BeforeSendData -= BeforeSendData;
    
    
                Trace.WriteLine(string.Format("session:{0} removed from clientItems", e.Session.ID));
                //foreach (Session s in clientItems.Values)
                //{
                //    Trace.WriteLine("Client Items is:----");
                //    Trace.WriteLine("               " + s.ID.ToString());
                    
                //}
    
            }
    
            /// 
            /// session_AfterReceivedData,after a received data is got, set the session to begin to receive,
            /// and you can do something else by yourself.ie:got the data, print them or store them in your code.
            /// 
            /// sender
            /// AfterReceivedDataEventArgs info
            protected virtual void session_AfterReceivedData(object sender, AfterReceivedDataEventArgs e)
            {
                lock (_syncObject)
                {
                    if (false == disposed)
                    {
                        Session session = sender as Session;
                        session.BeginReceiveData();
    
                        //do yourself thing.ie:got the data, print them or store them in your code.
                        if (AfterReceivedData != null)
                            AfterReceivedData(sender, e);
                    }
                }
            }
    
            /// 
            /// BeginSendData(Session session,byte[] data)
            /// 
            /// session that will got the data
            /// data that will be sent
            public void BeginSendData(Session session,byte[] data)
            {
                session.BeginSendData(data);
            }
    
            /// 
            /// OnStop , call the dispose.
            /// 
            public void OnStop()
            {
                Dispose();
            }
    
    
            #region IDisposable Members
    
            protected virtual void Dispose(bool disposing)
            {
                if (disposed)
                    return;
                
                lock (this)
                {
                    disposed = true;
    
                    if (disposing)
                    {
                        //release managed resource
                        // clean the session list.close them one by one.
                        foreach (Session s in clientItems.Values)
                        {
                            s.Close();
                            s.AfterReceivedData -= session_AfterReceivedData;
                            s.SessionTerminated -= session_SessionTerminated;
                            s.BeforeSendData -= BeforeSendData;
                        }
                        //clean the listener.
                        if (listener != null && listener.Connected)
                        {
                            listener.Shutdown(SocketShutdown.Both);
                            listener.Close();
                            listener = null;
                        }
    
                        
    
                       
                    }
    
                    //release unmanaged resource;
                    
                }
            }
    
            public void Dispose()
            {
                Dispose(true);
                GC.SuppressFinalize(this);
            }
    
            ~Server()
            {
                Dispose(false);
            }
    
    
            #endregion
    
        }
    }

    ServerFactory.cs

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Configuration;
    
    namespace MySocket
    {
        /// 
        /// ServerFactory
        /// 
        public class ServerFactory
        {
            protected static readonly object _lock = new object();
            static protected Server instance = null;
            
            private string strIpAddress;
            private int port;
            private int bufferSize;
    
            /// 
            /// Server IpAddress
            /// 
            public string StrIpAddress { get { return strIpAddress; } set { strIpAddress = value; } }
    
            /// 
            /// Port
            /// 
            public int Port { get { return port; } set { port = value; } }
    
            /// 
            /// BufferSize
            /// 
            public int BufferSize { get { return bufferSize; } set { bufferSize = value; } }
    
            /// 
            /// ServerFactory
            /// 
            private ServerFactory()
            {
                try
                {
                    strIpAddress = ConfigurationManager.AppSettings["ServerIpAddress"];
                    port = int.Parse(ConfigurationManager.AppSettings["ServerSocketPort"]);
                    bufferSize = int.Parse(ConfigurationManager.AppSettings["ServerSocketBufferSize"]);
    
                    instance = new Server(strIpAddress, port, bufferSize);
                    instance.Backlog = 100;
    
                }
                catch (Exception e)
                {
                    //AsgwExceptionHandler.Write(tmpEx);
                    throw new Exception("Socket Server param must be configured in the config file!", e);
                }
            }
    
            /// 
            /// CreateInstance,return the sington server
            /// 
            /// 
            public static Server CreateInstance()
            {
                if (instance == null)
                {
                    lock (_lock)
                    {
                        if (instance == null)
                        {
                            new ServerFactory();
                        }
                    }
                }
                return instance;
            }
    
        }
    }
    

     

    Session.cs

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Net.Sockets;
    using System.Diagnostics;
    using System.Threading;
    
    namespace MySocket
    {
        public class Session
        {
            int id;
            Socket socket;
    
            private bool _shuttingDown = false;
            private object _syncObject = new object();
    
            byte[] buffer ;//pre received data buffer.
    
            private int bufferSize; //pre received data buffer size.
    
            internal Session(int id, Socket socket, int bufferSize)
            {
                this.socket = socket;
                this.id = id;
                this.bufferSize=bufferSize;
                buffer=new byte[this.bufferSize];
            }
    
            public Socket Socket { get { return socket; } set { socket = value; } }
    
            internal byte[] Buffer { get { return buffer; } set { buffer = value; } }
    
            internal int ID { get { return id; } private set { id = value; } }
    
            internal event EventHandler AfterReceivedData;
    
            internal event BeforeSendDataEventHandler BeforeSendData;
    
            internal event EventHandler SessionTerminated;
    
            /// 
            /// BeginReceiveData
            /// 
            internal void BeginReceiveData()
            {
                try
                {
                    lock (_syncObject)
                    {
                        if (false == _shuttingDown)
                        {
                            AsyncCallback recieveData = new AsyncCallback(RecievedDataCallBack);
                            socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, recieveData, socket);
                            Trace.WriteLine("buffer:" + Encoding.Default.GetString(buffer));
                        }
                        else
                        {
                            //may be here will some error, but i can't test it out.
                            socket.Close();
                        }
                    }
                }
                catch (Exception ex)
                {
                    Trace.WriteLine("Recieve callback setup failed! {0}", ex.Message);
                }
            }
    
            internal void RecievedDataCallBack(IAsyncResult ar)
            {
                if (false == _shuttingDown)
                {
                    //GetReceivedData,call EndReceive
                    byte[] aryRet = GetReceivedData(ar);
                    
                    // If no data was recieved then the connection is probably dead
                    if (aryRet.Length < 1)
                    {
                        //call the methos, call the socket.Close(),in the CloseTheSocket() fun, just call the delegate
                        CloseTheSocket();
                        return;
                    }
                    // data is received
    
                    //if BeforeSendData is not null, when a received data is got ,it will send a back msg.
                    // you can set the send data in your code by set the methos 'BeforeSendData'
                    if (BeforeSendData != null)
                        BeginSendData(aryRet);
    
    
                    //if AfterReceivedData is not null,will call the dalegate,in the delegate,it will begin to receive data again.loop.
                    if (AfterReceivedData != null)
                        AfterReceivedData(this, new AfterReceivedDataEventArgs(aryRet));
    
    
                }
            }
    
            /// 
            /// call the socket.Close(),in the CloseTheSocket() fun, just call the delegate in server.
            /// 
            private void CloseTheSocket()
            {
                Trace.WriteLine(string.Format("Client {0}, CloseTheSocket", socket.RemoteEndPoint));
    
                if (SessionTerminated != null)
                    SessionTerminated(this, new SessionTerminateEventArgs(this));
            }
    
            /// 
            /// GetReceivedData,
            /// 
            /// 
            /// 
            internal byte[] GetReceivedData(IAsyncResult ar)
            {
                int nBytesRec = 0;
                try
                {
                    nBytesRec = socket.EndReceive(ar);
                }
                catch (Exception e)
                { // if some network problem happen, EndReceive will throw,ie:SocketException. here not care them,just call CloseTheSocket.
                    Trace.WriteLine("EndReceive:" + e.Message);
                    CloseTheSocket();
                }
    
                // accord to the actual received data length,copy the buffer to new.buffer,then return it.
                byte[] byReturn = new byte[nBytesRec];
                Array.Copy(buffer, byReturn, nBytesRec);
                Trace.WriteLine("byReturn:" + Encoding.Default.GetString(byReturn));
                return byReturn;
            }
    
            /// 
            /// BeginSendData
            /// 
            /// the beginreceived() methos got
            internal void BeginSendData(byte[] data)
            {
                byte[] dataWillSend = data;
                lock (_syncObject)
                {
                    if (false == _shuttingDown)
                    {
                        if (socket != null & socket.Connected)
                        {
                            try
                            {
                                //BeforeSendData is not null ,it will set the data before send.
                                if (BeforeSendData != null)
                                    dataWillSend = BeforeSendData(this, new BeforeSendDataEventArgs(data));
    
    
                                AsyncCallback sendData = new AsyncCallback(SentDataCallBack);
                                socket.BeginSend(dataWillSend, 0, dataWillSend.Length, SocketFlags.None, sendData, socket);
                            }
                            catch (Exception ex)
                            {
                                Trace.WriteLine("Send Message Failed! " + ex.Message);
                            }
                        }
                        else
                        {
                            Trace.WriteLine("Send message failed, socket is null or nonconnected.");
                        }
                    }
                    else
                    {
                        Trace.WriteLine("Send message failed, socket is shutting down.");
                    }
                }
            }
    
            /// 
            /// SentDataCallBack
            /// 
            /// 
            protected void SentDataCallBack(IAsyncResult ar)
            {
                Socket sock = (Socket)ar.AsyncState;
                
                try
                {
                    int nBytes = sock.EndSend(ar);
                    Trace.WriteLine("data is sent,length is" + nBytes);
                }
                catch (Exception ex)
                {
                    ////if Exception happen,ie:SocketException,close the socket.
                    CloseTheSocket();
                    Trace.WriteLine("EndSend error" + ex.Message);
                }
                
            }
    
            /// 
            /// set the _shuttingDown flag,
            /// close the socket.
            /// 
            internal void Close()
            {
                lock (_syncObject)
                {
                    _shuttingDown = true;
                }
    
                if (socket != null && socket.Connected)
                {
                    socket.Shutdown(SocketShutdown.Both);
                    socket.Close();
                    
                }
            }
    
    
        }
    }
    

    client 段的代码:

    app.config:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <appSettings>
        <add key="ServerIpAddress" value="10.13.12.15"/>
        <add key="ServerSocketPort" value="399"/>
        <add key="ClientSocketBufferSize" value="100"/>
        <add key="ClientSocketInterval" value="20000"/> <!--以毫秒为单位-->
      </appSettings>
    </configuration>

     

    Program.cs:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using SocketClient;
    using System.Diagnostics;
    using System.Threading;
    
    namespace ClientConsole
    {
        class Program
        {
            public static void Main()
            {
                Console.WriteLine("Main starting ");
    
                //test();
    
                test2();
    
                Console.ReadLine();
            }
            public static void test()
            {
                Client c1 = ClientFacotry.CreateInstance();
                c1.AfterReceivedData += new EventHandler(c_AfterReceivedData);
                c1.AfterRetyrFailed += new EventHandler(c_AfterRetyrFailed);
    
    
    
    
    
                while (true)
                {
                    Console.WriteLine("input string(\r\n1:start , \r\n2:send ,\r\n3:close ,\r\n4 nonstop sendata(close the app to stop): ");
    
                    string inputstr = "";
                    inputstr = Console.ReadLine();
                    if (inputstr == "0")
                        break;
                    else if (inputstr == "1")
                    {
                        c1.OnStart();
                    }
                    else if (inputstr == "2")
                    {
                        Console.WriteLine("input send strings: ");
                        string inputsendstr = Console.ReadLine();
                        byte[] data = Encoding.Default.GetBytes(inputsendstr);
                        c1.BeginSendData(data);
                    }
                    else if (inputstr == "3")
                    {
                        c1.OnStop();
                    }
                    else if (inputstr == "4")
                    {
                        while (true)
                        {
                            Thread.Sleep(1000);
                            DateTime now=DateTime.Now;
                            string str= "<" +now.Minute.ToString()+"-"+now.Second.ToString()+"-"+ now.Millisecond + ">";
                            c1.BeginSendData(Encoding.Default.GetBytes(str));
                        }
                    }
                    
    
                  
                }
    
            }
    
            static void test2()
            {
                for(int i=0;i<10;i++)
                {
                    Thread t = new Thread(setclient);
                    t.Name = "thread-" + i + "<" + DateTime.Now.ToLongTimeString()+">";
    
                    Thread.Sleep(i*1000);
                    t.Start(" ["+t.Name + "] "+DateTime.Now.ToLongDateString());
                }
    
            }
    
            static void setclient(object data)
            {
                Client c1 = ClientFacotry.CreateInstance();
                c1.AfterReceivedData += new EventHandler(c_AfterReceivedData);
                c1.AfterRetyrFailed += new EventHandler(c_AfterRetyrFailed);
    
                c1.OnStart();
                while (true)
                {
                    int secnd=DateTime.Now.Second;
                    string str = data.ToString() + " sleep: " + secnd+" ";
    
                    Thread.Sleep(secnd * 1000);
                    c1.BeginSendData(Encoding.Default.GetBytes(str));
                }
    
            }
    
            static void c_AfterRetyrFailed(object sender, AfterReTryFailedEventArgs e)
            {
    
                //e.Client.Dispose();
                Trace.WriteLine("retry failed, object disposed");
            }
    
            static void c_AfterReceivedData(object sender, AfterReceivedDataEventArgs e)
            {
                string s = Encoding.Default.GetString(e.Data);
                Trace.WriteLine("Received data:" + s);
            }
        }
    }
    

     

    ClientFacor

     

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Configuration;
    
    namespace SocketClient
    {
        /// 
        /// ClientFacotry ,create socket client
        /// 
        public class ClientFacotry
        {
            protected static readonly object _lock = new object();
            static protected ClientFacotry instance = null;
    
            private string strServerIpAddress;
            private int serverPort;
            private int bufferSize;
            private int clientInterval;
    
            /// 
            /// StrServerIpAddress
            /// 
            public string StrServerIpAddress { get { return strServerIpAddress; } set { strServerIpAddress = value; } }
    
            /// 
            /// ServerPort
            /// 
            public int ServerPort { get { return serverPort; } set { serverPort = value; } }
    
            /// 
            /// BufferSize
            /// 
            public int BufferSize { get { return bufferSize; } set { bufferSize = value; } }
    
            /// 
            /// ClientInterval
            /// 
            public int ClientInterval { get { return clientInterval; } set { clientInterval = value; } }
    
    
            /// 
            /// ClientFacotry
            /// 
            private ClientFacotry()
            {
                try
                {
                strServerIpAddress = ConfigurationManager.AppSettings["ServerIpAddress"];
                serverPort = int.Parse(ConfigurationManager.AppSettings["ServerSocketPort"]);
                bufferSize = int.Parse(ConfigurationManager.AppSettings["ClientSocketBufferSize"]);
                clientInterval = int.Parse(ConfigurationManager.AppSettings["ClientSocketInterval"]);
    
                }
                catch (Exception e)
                {
                    //AsgwExceptionHandler.Write(tmpEx);
                    throw new Exception("Socket Client param must be configured in the config file!", e);
                }
    
            }
    
            /// 
            /// CreateInstance,return a new client
            /// 
            /// 
            public static Client CreateInstance()
            {
                if (instance == null)
                {
                    lock (_lock)
                    {
                        if (instance == null)
                        {
                            instance=new ClientFacotry();
                        }
                    }
                }
                if (instance != null)
                {
                    Client client = new Client(instance.strServerIpAddress, instance.serverPort, instance.bufferSize, instance.clientInterval);
                    return client;
                }
    
                return null;
            }
    
        }
    }
    

    Client.cs

    using System.Net;
    
    using System.Net.Sockets;
    
    using System.Text;
    using System;
    using System.Threading;
    
    namespace SocketClient
    {
        /// 
        /// Socket client,send data to server.
        /// 
        public class Client:IDisposable
        {
    
            private Socket socket;
            private byte[] byBuff;//this buff is used for received.
            int receivedBufferSize; //pre received buffer length.
            private string strServerIPAddress;
            private int port;
            private IPEndPoint epServer;
    
            static AutoResetEvent timerWaitHandle = new AutoResetEvent(false);
            private Timer tryTimer;
            private int elapsedTime;
            private bool tryTimeOutTerminationInitiated = false;
            private const int TRY_TIME_OUT = 5;
            private int timerInterval = 1000;//毫秒
            private bool enableTimeOut = false;
    
            private ManualResetEvent SendDataWaitHandle = new ManualResetEvent(false);
    
            private bool disposed = false;
            private object _syncObject = new object();
    
            public event EventHandler AfterReceivedData;
            public event EventHandler AfterRetyrFailed;
    
    
            public Socket Socket { get { return socket; } set { socket = value; } }
    
            public string StrServerIPAddress { get { return strServerIPAddress; } set { strServerIPAddress = value; } }
    
            public int Port { get { return port; } set { port = value; } }
    
            public Timer TryTimer { get { return tryTimer; } set { tryTimer = value; } }
    
    
    
    
            /// 
            /// new a client object
            /// 
            /// ipAddress string type
            /// port
            /// pre receive data buffer size.
            /// the timer that loop to connect to server if server is not avalible.(毫秒为单位)
            public Client(string ipAddress,int port,int receivedBufferSize,int timerInterval)
            {
                try
                {
                    this.strServerIPAddress = ipAddress;
    
                    this.port = port;
                    this.receivedBufferSize = receivedBufferSize;
                    this.byBuff = new byte[receivedBufferSize];
                    this.timerInterval = timerInterval;
                }
                catch (Exception ex)
                {
                    
                    Trace.WriteLine("Server Connect failed! error: "+ex.Message);
                }
            }
    
            /// 
            /// SocketConneted or not
            /// 
            private bool IsSocketConneted
            {
                get
                {
                    lock (_syncObject)
                    {
                        return   this.socket!=null && this.socket.Connected ;
                    }
              
                }
            
            }
    
            /// 
            /// OnStart, start the client to connetced.
            /// 
            public void OnStart()
            {
                Timer Timer = null;
                AutoResetEvent tmrWtHdlr = null;
    
                lock (_syncObject)
                {
                    tmrWtHdlr = timerWaitHandle;
                    Timer = tryTimer;
    
    
                    elapsedTime = 0;
                    tryTimeOutTerminationInitiated = false;
                    disposed = false;
                    SendDataWaitHandle.Reset();
                    
                }
    
                if (tmrWtHdlr != null)
                {
                    Timer = new Timer(
                        new TimerCallback(this.TimerCallback), tmrWtHdlr,
                         0, this.timerInterval);
                    
                }
                
    
    
                lock (_syncObject)
                {
                    tryTimer = Timer;
                    timerWaitHandle = tmrWtHdlr;
                }
                
            }
    
            /// 
            /// BeginConnectToServer
            /// 
            protected void BeginConnectToServer()
            {
                try
                {
                    //if the socket is open ,then closed it first.
                    if (socket != null && socket.Connected)
                    {
                        socket.Shutdown(SocketShutdown.Both);
                        socket.Close();
                    }
    
                    socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    
                    epServer = new IPEndPoint(IPAddress.Parse(strServerIPAddress), port);
    
                    socket.Blocking = true;
    
                    AsyncCallback onconnect = new AsyncCallback(OnConnect);
                    socket.BeginConnect(epServer, onconnect, socket);
                }
                catch (Exception ex)
                {
                    Trace.WriteLine("Connect error: " + ex.Message);
                }
            }
    
            protected void OnConnect(IAsyncResult ar)
            {
                // Socket was the passed in object
                Socket sock = (Socket)ar.AsyncState;
                Trace.WriteLine("OnConnect called");
                // Check if we were sucessfull
                try
                {
                    //sock.EndConnect(ar);
                    if (sock.Connected)
                    {   
                        //begin to received.
                        SetupRecieveCallback(sock);
    
                        lock (_syncObject)
                        {
                            this.elapsedTime = 0;
                            this.tryTimeOutTerminationInitiated = false;
    
                            SendDataWaitHandle.Set();
                        }
                    }
                    else
                    {
                        SendDataWaitHandle.Reset();
                        Trace.WriteLine("Unable to connect to remote machine, Connect Failed!, it will try again");                  
                    }
                }
                catch (SocketException sex)
                {
                    Trace.WriteLine("SocketException:" + sex.Message);
                }
                catch (Exception ex)
                {
                    Trace.WriteLine(ex.Message + "     \r\nUnusual error during Connect!");
                }
            }
    
            /// 
            /// SetupRecieveCallback
            /// 
            /// 
            protected void SetupRecieveCallback(Socket sock)
            {
                try
                {
                    
                    AsyncCallback recieveData = new AsyncCallback(OnRecievedData);
                    sock.BeginReceive(byBuff, 0, byBuff.Length, SocketFlags.None, recieveData, sock);
                    Trace.WriteLine("byBuff:" + Encoding.Default.GetString(byBuff));
                }
                catch (Exception ex)
                {
                    Trace.WriteLine("Setup Recieve Callback failed: "+ex.Message);
                }
            }
    
            protected void OnRecievedData(IAsyncResult ar)
            {
                Trace.WriteLine("EndReceive called");
                if (false == disposed)
                {
                    // Socket was the passed in object
                    Socket sock = (Socket)ar.AsyncState;
                    int nBytesRec = 0;
                    // Check if we got any data
                    try
                    {
                        try
                        {
                            nBytesRec = sock.EndReceive(ar);
                        }
                        catch (SocketException ex)
                        {
                            //for some network problem,the socket will throw the SocketException,
                            //if Exception happen,ie:SocketException,close the socket.
                            CloseSocket();
                            Trace.WriteLine("EndReceive:" + ex.Message);
                        }
    
                        //Trace.WriteLine("sock.RemoteEndPoint:" + sock.RemoteEndPoint.ToString());
                        if (nBytesRec < 1)
                        {
                            // If no data was recieved then the connection is probably dead
                            Trace.WriteLine(string.Format("Client {0}, disconnected", sock.RemoteEndPoint));
                            CloseSocket();
                            return;
                        }
    
                        byte[] byReturn = new byte[nBytesRec];
                        Array.Copy(byBuff, byReturn, nBytesRec);
    
                        Trace.WriteLine("byReturn:" + Encoding.Default.GetString(byReturn));
    
                        OnAfterReceivedData(this, new AfterReceivedDataEventArgs(byReturn));
    
                        // If the connection is still usable restablish the callback
                        SetupRecieveCallback(sock);
    
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Unusual error druing Recieve :" + ex.Message);
                    }
                }
            }
    
            /// 
            /// OnAfterReceivedData, you can override in your sub class
            /// 
            /// 
            /// 
            protected virtual void OnAfterReceivedData(object sender, AfterReceivedDataEventArgs e)
            {
                if (AfterReceivedData != null)
                    AfterReceivedData(sender, e);
            }
    
            /// 
            /// OnAfterRetryFailed, you can override in your sub class
            /// 
            /// 
            /// 
            protected virtual void OnAfterRetryFailed(object sender, AfterReTryFailedEventArgs e)
            {
                if (AfterRetyrFailed != null)
                    AfterRetyrFailed(sender, e);
            }
    
            /// 
            /// SendData
            /// 
            /// 
            public void BeginSendData(byte[] data)
            {
                //before the connect is establish,wait..
                SendDataWaitHandle.WaitOne();
    
                if (null != data && data.Length > 0)
                {
                    if (IsSocketConneted)
                    {
                        try
                        {
                            // Convert to byte array and send.
                            AsyncCallback sendData = new AsyncCallback(OnSentData);
                            Byte[] byteDateLine = data;
                            socket.BeginSend(byteDateLine, 0, byteDateLine.Length, SocketFlags.None, sendData, socket);
                            Trace.WriteLine("will send data:" + Encoding.Default.GetString(byteDateLine) + " , length will be: " + byteDateLine.Length);
                        }
                        catch (Exception ex)
                        {
                            Trace.WriteLine(ex.Message + " \r\nSend Message Failed!");
                        }
                    }
                    else
                    {
                        Trace.WriteLine("Must be connected to Send a message");
                    }
                }
            }
    
            protected void OnSentData(IAsyncResult ar)
            {
                Socket sock = (Socket)ar.AsyncState;
                try
                {
                    int nBytes = sock.EndSend(ar);
                    Trace.WriteLine("sent data actual legth:" + nBytes); 
                }
                catch (Exception ex)
                {
                    //if Exception happen,ie:SocketException,close the socket.
                    CloseSocket();
                    Trace.WriteLine("EndSend error" + ex.Message);
                }
            }
    
            /// 
            /// OnStop , call Dispose.
            /// 
            public void OnStop()
            {
                Dispose();
            }
    
            /// 
            /// CloseSocket
            /// 
            protected void CloseSocket()
            {
                if (socket != null && socket.Connected)
                {
                    //below will close the socket,first blok the SendData method.
                    SendDataWaitHandle.Reset();
                    //close the socket
                    socket.Shutdown(SocketShutdown.Both);
                    socket.Close();
                    Trace.WriteLine("socket shutting down");
                    //socket = null;
                }
    
                
    
                //clean the buffer
    
            }
    
            private int tc = 0;
    
            private void TimerCallback(Object obj)
            {
    
                bool tryTimeOutTerminationInitiated;
               // AutoResetEvent tmrWtHdlr = null;
                int elapsedTime = 0;
                bool shuttingDown;
                bool socketConnected;
    
                lock (_syncObject)
                {
                    elapsedTime = this.elapsedTime;
                    //tmrWtHdlr = timerWaitHandle;
                    tryTimeOutTerminationInitiated = this.tryTimeOutTerminationInitiated;
                    shuttingDown = this.disposed;
                    socketConnected = IsSocketConneted;
    
                }
                int Id = Interlocked.Increment(ref tc);
                Trace.WriteLine(Id.ToString()+" : socketConnected:" + socketConnected.ToString());
    
                if (false == shuttingDown)
                {
                    if (!socketConnected)
                    {
                        
                        elapsedTime += 1;
                        Trace.WriteLine("elapsedTime:" + elapsedTime.ToString());
    
                        if (!tryTimeOutTerminationInitiated)
                        {
    
                            if (enableTimeOut && elapsedTime >= TRY_TIME_OUT)
                            {
                                tryTimeOutTerminationInitiated = true;
                                
                                //close socket
                                CloseSocket();
                                
                                //clean the timer,if time out,stop the timer.
                                if (tryTimer != null)
                                    tryTimer.Dispose();
    
                                //you can do something after time out failed.
                                OnAfterRetryFailed(this, new AfterReTryFailedEventArgs(this));
    
                            }
                            else
                            {
                                // retry connect
                                BeginConnectToServer();
                            }
                        }
                    }
                }
    
                lock (_syncObject)
                {
                    this.elapsedTime = elapsedTime;
                    //timerWaitHandle = tmrWtHdlr;
                    this.tryTimeOutTerminationInitiated = tryTimeOutTerminationInitiated;
                }
            }
    
    
             #region IDisposable Members
    
            protected virtual void Dispose(bool disposing)
            {
                if (disposed)
                    return;
                
                lock (this)
                {
                    disposed = true;
    
                    if (disposing)
                    {
                        Trace.WriteLine("disposing..");
    
                        //release managed resource
                        CloseSocket();
    
                        //clean the timer
                        if (tryTimer != null)
                            tryTimer.Dispose();
                       
                    }
    
                    //release unmanaged resource;
                    //...
    
                }
            }
    
            public void Dispose()
            {
                Dispose(true);
                GC.SuppressFinalize(this);
            }
    
            ~Client()
            {
                Dispose(false);
            }
    
    
            #endregion
    
            
            private class Trace
            {
    
                public static void WriteLine(string msg)
                {
                    string threadname = Thread.CurrentThread.Name;
    
    
                   // Console.WriteLine(threadname+"->"+msg);
    
                    System.Diagnostics.Trace.WriteLine(msg);
                }
            }
    
        }
    }

     EventArgs.cs:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace SocketClient
    {
        public class AfterReceivedDataEventArgs:EventArgs
        {
            byte[] data;
            public byte[] Data { get { return data; } set { data = value; } }
    
            public AfterReceivedDataEventArgs(byte[] data)
            {
                this.data = data;
            }
        }
    
        public class AfterReTryFailedEventArgs:EventArgs
        {
            Client client;
            public Client Client { get { return client; } set { client = value; } }
    
            public AfterReTryFailedEventArgs(Client client)
            {
                this.client = client;
            }
        }
    
    }
    

    下载地址:

    http://download.csdn.net/source/479391

    个人感觉这个dispose 接口 不知道是否真的把资源释放干净了,代理的 -= 是否把所有的代理都清理了,还有其他很多问题,自己仅仅是很简单的测了一下。 希望高人给点意见。

    感觉自己还有很多不足的地方,诚心希望大家给点批评意见。(csdn这个编辑器好垃圾,我插入了c# 代码,怎么还没有变色,全是白底黑字。非要自己开发修改blog,但又搞的这么差劲,就知道到处嵌广告)

     

     

    发表于 @ 2008年06月02日 10:27:00|评论(loading...)|编辑

    新一篇: 为MMC编写服务器控制管理单元。插件方式 (MMC3.0 , installutil ,c#,KB907265,Enterprise Library) | 旧一篇: GC是如何工作的,不同的代的大小是多少

    评论:没有评论。

    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © baal