由于日常使用中经常需要调试tcp客户端程序,因此写了一个简单的tcpserver,能处理多客户端,接收它们的消息,同时对所有客户端发出消息。

为了使得防火墙不跳出警告,只实现对本地3000端口的监听,无法连接远程客户端。

代码如下:

    class Listener

    {

        TcpListener listener;

        List<TcpClient> clients = new List<TcpClient>();

 

        public Listener()

        {

            listener = new TcpListener(new IPEndPoint(IPAddress.Loopback, 3000)); 

        }

 

        public void Run()

        {

            System.Threading.ThreadPool.QueueUserWorkItem(x => send_message());

 

            Console.WriteLine("begin to get sockets...");

            listener.Start();

            while (true)

            {

                TcpClient client = listener.AcceptTcpClient();

                Console.WriteLine("get connect from:\t"+client.Client.RemoteEndPoint);

 

                clients.Add(client);

                begin_read(client, new byte[1024]);

            }

        }

 

        void send_message()

        {

            while (true)

            {

                string msg = Console.ReadLine();

                byte[] data = Encoding.Default.GetBytes(msg + "\r\n");

                Console.WriteLine("send:\t|" + msg + "|");

                foreach (var item in clients)

                {

                   

                    item.GetStream().Write(data, 0, data.Length);

                }

            }

        }

 

        void begin_read(TcpClient client, byte[] buffer)

        {

            client.GetStream().BeginRead(

                buffer, 0, buffer.Length,

                x => end_read(x, client, buffer),

                null);

        }

 

        void end_read(IAsyncResult ar, TcpClient client, byte[] buffer)

        {

            try

            {

                int count = client.GetStream().EndRead(ar);

 

                if (count == 0)

                {

                    Console.WriteLine("socket is closed.");

                    handle_err(new SocketException((int)SocketError.Disconnecting), client);

                    return;

                }

               

                Console.WriteLine("read:\t" + Encoding.Default.GetString(buffer, 0, count));

                begin_read(client, buffer);

            }

            catch (Exception e)

            {

                handle_err(e, client);

            }           

        }

 

        void handle_err(Exception e, TcpClient client)

        {

            client.Close();

            clients.Remove(client);

            Console.WriteLine(e.Message);

        }

 

这个程序主要是用于tcp程序的测试,不考虑效率问题(对效率有严格要求的地方一般就用C++写了,.net垃圾回收效率好像还是不行),不过这个服务器数据收发采用的是异步架构,效率应该不错。