C#类型关键字全部改为.Net类型,优先使用var
大石头 authored at 2017-03-26 09:01:31
13.09 KiB
X
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using NewLife.Log;
using NewLife.Net.Sockets;
using NewLife.Threading;

namespace NewLife.Net.Application
{
    /// <summary>网络应用程序测试</summary>
    public static class AppTest
    {
        #region 基础服务测试
        /// <summary>开始测试</summary>
        public static void Start()
        {
            StartServer();
            StartClient();
        }

        /// <summary>开始测试</summary>
        public static void StartServer()
        {
            var ts = new Type[] { typeof(ChargenServer), typeof(DaytimeServer), typeof(DiscardServer), typeof(EchoServer), typeof(TimeServer) };
            //var ts = new Type[] { typeof(EchoServer) };
            var list = new List<NetServer>();
            foreach (var item in ts)
            {
                var server = Activator.CreateInstance(item) as NetServer;
                server.Start();
                list.Add(server);
            }
        }

        /// <summary>开始测试</summary>
        public static void StartClient()
        {
            StartEchoServer(7);
            StartDaytimeServer(13);
            StartTimeServer(37);
            StartDiscardServer(9);
            StartChargenServer(19);
        }

        static AutoResetEvent _are = new AutoResetEvent(true);
        static void OnReceived(Object sender, ReceivedEventArgs e)
        {
            var session = sender as ISocketSession;
            Console.WriteLine("客户端{0} 收到 [{1}]: {2}", session, e.Stream.Length, e.Stream.ToStr());

            _are.Set();
        }

        static void OnError(Object sender, ExceptionEventArgs e)
        {
            Console.WriteLine("客户端{0}错误 {1}", sender, e.Exception);
        }

        static void TestSend(String name, NetUri uri, Boolean isAsync, Boolean isSendData, Boolean isReceiveData)
        {
            Console.WriteLine();

            var msg = String.Format("{0}Test_{1}_{2}!", name, uri.Type, isAsync ? "异步" : "同步");
            var client = uri.CreateRemote();
            client.Error += OnError;
            if (isAsync && isReceiveData)
            {
                _are.Reset();
                client.Received += OnReceived;
                client.Open();
            }
            if (isSendData) client.Send(msg);

            var rs = false;
            if (isReceiveData)
            {
                if (!isAsync)
                {
                    try
                    {
                        //Console.WriteLine("客户端" + session + " " + session.ReceiveString());
                        var pk = client.Receive();
                        Console.WriteLine("客户端{0} 收到 [{1}]: {2}", client, pk.Count, pk.ToStr());

                        rs = true;
                    }
                    catch (Exception ex)
                    {
                        Debug.Fail("同步超时!" + ex.Message);
                    }
                }
                else
                {
                    if (!_are.WaitOne(2000))
                        Debug.Fail("异步超时!");
                    else
                        rs = true;
                }
            }
            client.Dispose();
            client = null;
            GC.Collect();

            XTrace.WriteLine(rs ? "成功!" : "失败!");
        }

        static void TestSends(String name, IPEndPoint ep, Boolean isSendData, Boolean isReceiveData = true)
        {
            //if (ep.AddressFamily == AddressFamily.InterNetworkV6) return;

            Console.WriteLine();
            Console.WriteLine("{0}:", name);
            //TestSend(name, ProtocolType.Udp, ep, false, isSendData, isReceiveData);
            //TestSend(name, ProtocolType.Udp, ep, true, isSendData, isReceiveData);
            //TestSend(name, ProtocolType.Tcp, ep, false, isSendData, isReceiveData);
            //TestSend(name, ProtocolType.Tcp, ep, true, isSendData, isReceiveData);
            var uri = new NetUri(NetType.Udp, ep);
            TestSend(name, uri, false, isSendData, isReceiveData);
            TestSend(name, uri, true, isSendData, isReceiveData);
            uri.Type = NetType.Tcp;
            TestSend(name, uri, false, isSendData, isReceiveData);
            TestSend(name, uri, true, isSendData, isReceiveData);

            GC.Collect();
        }

        static void StartEchoServer(Int32 port)
        {
            var ep = new IPEndPoint(IPAddress.Loopback, port);

            TestSends("Echo", ep, true);

            ep = new IPEndPoint(IPAddress.IPv6Loopback, port);

            TestSends("Echo IPv6", ep, true);
        }

        static void StartDaytimeServer(Int32 port)
        {
            var ep = new IPEndPoint(IPAddress.Loopback, port);

            TestSends("Daytime", ep, true);

            ep = new IPEndPoint(IPAddress.IPv6Loopback, port);

            TestSends("Daytime IPv6", ep, true);
        }

        static void StartTimeServer(Int32 port)
        {
            var ep = new IPEndPoint(IPAddress.Loopback, port);

            TestSends("Time", ep, true);

            ep = new IPEndPoint(IPAddress.IPv6Loopback, port);

            TestSends("Time IPv6", ep, true);
        }

        static void StartDiscardServer(Int32 port)
        {
            var ep = new IPEndPoint(IPAddress.Loopback, port);

            TestSends("Discard", ep, true, false);

            ep = new IPEndPoint(IPAddress.IPv6Loopback, port);

            TestSends("Discard IPv6", ep, true, false);
        }

        static void StartChargenServer(Int32 port)
        {
            var ep = new IPEndPoint(IPAddress.Loopback, port);

            TestSends("Chargen", ep, true);

            ep = new IPEndPoint(IPAddress.IPv6Loopback, port);

            TestSends("Chargen IPv6", ep, true);
        }
        #endregion

        #region TCP大量连接测试
        /// <summary>TCP大量连接测试</summary>
        public static void TcpConnectionTest()
        {
            while (true)
            {
                Console.Write("请选择模式:(1,服务端 2,客户端)");
                var str = Console.ReadLine();

                if (str == "1")
                {
                    TestServer();
                    break;
                }
                else if (str == "2")
                {
                    TestClient();
                    break;
                }
            }
        }

        static NetServer server = null;
        static void TestServer()
        {
            var port = ReadInt("请输入监听端口:", 1, 65535);

            // 扩大事件池
            //NetEventArgs.Pool.Max = 200000;

            server = new NetServer();
            server.ProtocolType = NetType.Tcp;
            server.Port = port;
            server.UseSession = true;
            server.Received += server_Received;
            // 最大不活跃时间设为10分钟
            foreach (var item in server.Servers)
            {
                item.SessionTimeout = 10 * 60;
            }
            server.Start();
            server.Log = null;

            Task.Factory.StartNew(ShowStatus);

            Console.WriteLine("服务端准备就绪,任何时候任意键退出服务程序!");
            Console.ReadKey(true);

            server.Dispose();
        }

        static void server_Received(Object sender, ReceivedEventArgs e)
        {
            OnReceive(sender as ISocketSession, e.Stream);
        }

        /// <summary>已重载。</summary>
        /// <param name="session"></param>
        /// <param name="stream"></param>
        static void OnReceive(ISocketSession session, Stream stream)
        {
            if (stream.Length == 0) return;

            asyncCount++;

            //if (stream.Length > 100)
            //    Console.WriteLine("Echo {0} [{1}]", session.Remote, stream.Length);
            //else
            //    Console.WriteLine("Echo {0} [{1}] {2}", session.Remote, stream.Length, e.GetString());
            //var p = stream.Position;
            //var msg = "";
            //if (stream.Length > 100)
            //    msg = String.Format("Echo {0} [{1}]", session.Remote, stream.Length);
            //else
            //    msg = String.Format("Echo {0} [{1}] {2}", session.Remote, stream.Length, stream.ToStr());

            ////session.Send(e.Buffer, e.Offset, stream.Length);
            //stream.Position = p;
            session.Send(stream);
        }

        static Int32 asyncCount = 0;
        static void ShowStatus()
        {
            while (true)
            {
                try
                {
                    var wt = 0;
                    var cpt = 0;
                    ThreadPool.GetAvailableThreads(out wt, out cpt);
                    var threads = Process.GetCurrentProcess().Threads.Count;

                    var color = Console.ForegroundColor;
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    //Console.WriteLine("异步:{0} 会话:{1} Thread:{2}/{3}/{4} Pool:{5}/{6}/{7}", asyncCount, server.Sessions.Count, threads, wt, cpt, pool.StockCount, pool.FreeCount, pool.CreateCount);
                    //var count = server.Sessions.Count;
                    var count = server.SessionCount;
                    Console.WriteLine("消息:{0} 会话:{1} Thread:{2}/{3}/{4}", asyncCount, count, threads, wt, cpt);
                    Console.ForegroundColor = color;
                }
                catch { }

                Thread.Sleep(3000);
            }
        }

        //static Thread[] threads;
        static void TestClient()
        {
            Console.Write("请输入服务器地址:");
            var host = Console.ReadLine();
            var port = ReadInt("请输入服务器端口:", 1, 65535);

            var ep = NetHelper.ParseEndPoint(host, port);
            var uri = new NetUri(NetType.Tcp, ep);

            Console.WriteLine("开始测试连接{0}……", uri);

            var session = uri.CreateRemote();
            session.Send("Hi");
            var rs = session.ReceiveString();
            session.Dispose();
            if (rs.IsNullOrWhiteSpace())
            {
                Console.WriteLine("连接失败!");
                return;
            }

            var threadcount = ReadInt("请输入线程数(建议20):", 1, 10000);
            var perthread = ReadInt("请输入每线程连接数(建议500):", 1, 10000);
            //var time = ReadInt("请输入连接间隔(毫秒,建议10毫秒):", 1, 10000);
            var time = 10;

            var threads = new Thread[threadcount];
            for (var i = 0; i < threadcount; i++)
            {
                var th = new Thread(ClientProcess);
                th.IsBackground = true;
                th.Priority = ThreadPriority.BelowNormal;
                th.Name = "Client_" + (i + 1);

                threads[i] = th;
                var p = new TCParam() { ID = i + 1, Count = perthread, Period = time, Uri = uri };
                th.Start(p);

                Thread.Sleep(100);
            }
        }

        static void ClientProcess(Object state)
        {
            var p = state as TCParam;

            var msg = String.Format("Hi I am {0}!", p.ID);

            var clients = new ISocketClient[p.Count];
            for (var k = 0; k < 100; k++)
            {
                Console.WriteLine("第{1}轮处理:{0}", p.ID, k + 1);

                for (var i = 0; i < p.Count; i++)
                {
                    try
                    {
                        var client = clients[i];
                        if (client == null || client.Disposed)
                        {
                            client = p.Uri.CreateRemote();

                            clients[i] = client;
                        }

                        client.Send(msg);
                    }
                    catch { }

                    if (p.Period > 0) Thread.Sleep(p.Period);
                }
            }
        }

        class TCParam
        {
            public Int32 ID;
            public Int32 Count;
            public Int32 Period;

            public NetUri Uri;
        }

        static Int32 ReadInt(String title, Int32 min, Int32 max)
        {
            if (String.IsNullOrEmpty(title))
                title = "请输入数字:";
            else if (title[title.Length - 1] != ':')
                title += ":";

            var n = 0;
            while (n < min || n > max)
            {
                Console.Write(title);
                var str = Console.ReadLine();
                if (!String.IsNullOrEmpty(str)) Int32.TryParse(str, out n);
            }
            return n;
        }
        #endregion
    }
}