首页 > 代码库 > C#下用select方法实现socket服务端

C#下用select方法实现socket服务端

select是一种比较古老但一直被证明性能很好的socket模式,它可以让你以消息驱动的模式书写socket程序。网上C++的例子很多,但C#的例子极少。

上代码:

namespace Server
{
    class Program
    {
        // Thread signal.
    public static ManualResetEvent allDone = new ManualResetEvent(false);

    private static Socket handler = null;
    private static ArrayList g_CliSocketArr = new ArrayList();
    private static Object thisLock = new Object();
    public Program()
    {
    }

    public static void StartListening() {
        // Data buffer for incoming data.
        byte[] bytes = new Byte[1024];

        
        IPAddress ipAddress = IPAddress.Parse("192.168.1.71");//
        IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);

        // Create a TCP/IP socket.
        Socket listener = new Socket(AddressFamily.InterNetwork,
            SocketType.Stream, ProtocolType.Tcp );
        
        // Bind the socket to the local endpoint and listen for incoming connections.
        try {
            listener.Bind(localEndPoint);
            listener.Listen(100);


            // Start an asynchronous socket to listen for connections.
            Console.WriteLine("Waiting for a connection...");

            Thread worker = new Thread(new ThreadStart(WorkerThread));//创建一个线程用于处理请求
            worker.Start();
            while (true)
            {
                Socket sClient = listener.Accept();
                Console.WriteLine("There is a new connection.");
                g_CliSocketArr.Add(sClient);
                
            }

        } catch (Exception e) {
            Console.WriteLine(e.ToString());
        }

        Console.WriteLine("\nPress ENTER to continue...");
        Console.Read();
        
    }
        public static void WorkerThread()
        {
            Socket socket1 = null;
            ArrayList readList = new ArrayList();
      //      readList.Add(socket0);
            while (true)
            {
                lock (thisLock)
                {
                    readList.Clear();
                    for (int i = 0; i < g_CliSocketArr.Count; i++)
                    {
                        readList.Add(g_CliSocketArr[i]);
                    }
                }
                if (readList.Count <= 0)
                {
                    Thread.Sleep(100);
                    continue;
                }
                try
                {
                    Socket.Select(readList, null, null, 500);
                    for (int i = 0; i < readList.Count; i++)
                    {
                        socket1 = (Socket)readList[i];
                        Console.WriteLine("There is a new message from client.");
                        byte[] buffer = new byte[1024];
                    
                            int recLen = socket1.Receive(buffer);
                            if(recLen > 0)
                            {
                            //    recLen = socket1.Receive(buffer);
                            }
                            else
                            {//如果返回0,表示客户端已经断开连接,须将此socket关闭然后从连接池中清除
                                Console.WriteLine("Rece 0 length.");
                                for (int ii = 0; ii < g_CliSocketArr.Count; ii++)
                                {
                                    Socket s = (Socket)g_CliSocketArr[ii];
                                    if (s == socket1)
                                        g_CliSocketArr.RemoveAt(ii);
                                }
                                socket1.Shutdown(SocketShutdown.Both);
                                socket1.Close();
                                break;
                            }
                            socket1.Send(buffer,recLen, SocketFlags.None);
                   
                    }
                }
                catch (SocketException e)
                {
                    Console.WriteLine("{0} Error code: {1}.", e.Message, e.ErrorCode);

                    for (int ii = 0; ii < g_CliSocketArr.Count; ii++)
                    {
                        Socket s = (Socket)g_CliSocketArr[ii];
                        if (s == socket1)
                            g_CliSocketArr.RemoveAt(ii);
                    }
                    socket1.Shutdown(SocketShutdown.Both);
                    socket1.Close();
                }
            }
            
        }

        static void Main(string[] args)
        {
            StartListening();
        }
 
    }

}