SuperSocket学习笔记(一)

  这是根据我自己学习的经历整理出来的,如有不对之处,还请多多指教!

SuperSocket源码下载  

SuperSocket文档

安装并启动Telnet

学习方法:

  QuickStrart + 文档

参考资料:

 

下面是一个例子的主要源码:

最终形成的目录:(Config文件夹中log4net.config文件来自SupertSocket源码)

SuperSocket学习笔记(一)

文件源码:

app.config

<?xml version="1.0"?>

<configuration>

  <startup>

    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>

  </startup>

  <runtime>

    <gcServer enabled="true" />

  </runtime>

</configuration>
View Code

ControlCommand.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;



using SuperSocket.SocketBase;



namespace ConsoleApp

{

    public class ControlCommand

    {

        public string Name { get; set; }



        public string Description { get; set; }



        public Func<IBootstrap, string[], bool> Handler { get; set; }

    }

}
View Code

HELLO.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;



using SuperSocket.SocketBase.Command;

using SuperSocket.SocketBase.Protocol;



namespace ConsoleApp

{

    /// <summary>  

    /// 自定义命令类HELLO,继承CommandBase,并传入自定义连接类MySession  

    /// </summary>  

    public class HELLO : CommandBase<MySession, StringRequestInfo>

    {

        /// <summary>

        /// 命令编号

        /// </summary>

        public override string Name

        {

            get { return "01"; }

        }

        /// <summary>  

        /// 自定义执行命令方法,注意传入的变量session类型为MySession  

        /// </summary>  

        /// <param name="session"></param>  

        /// <param name="requestInfo"></param>  

        public override void ExecuteCommand(MySession session, StringRequestInfo requestInfo)

        {

            session.Send("\r\nHello World!");

        }

    }  

}
View Code

MyServer.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;



using SuperSocket.SocketBase;



namespace ConsoleApp

{

    /// <summary>  

    /// 自定义服务器类MyServer,继承AppServer,并传入自定义连接类MySession  

    /// </summary> 

    public class MyServer : AppServer<MySession>  

    {

         protected override void OnStartup()  

        {  

            base.OnStarted();  

            Console.WriteLine("服务器已启动");  

        }  

  

        /// <summary>  

        /// 输出新连接信息  

        /// </summary>  

        /// <param name="session"></param>  

         protected override void OnNewSessionConnected(MySession session)

         {

             base.OnNewSessionConnected(session); 

             Console.Write("\r\n" + session.LocalEndPoint.Address.ToString() + ":连接");

         }



         /// <summary>  

         /// 输出断开连接信息  

         /// </summary>  

         /// <param name="session"></param>  

         /// <param name="reason"></param>  

         protected override void OnSessionClosed(MySession session, CloseReason reason)  

        {  

            base.OnSessionClosed(session, reason);

            Console.Write("\r\n" + session.LocalEndPoint.Address.ToString() + ":断开连接");  

        }



         protected override void OnStopped()

         {

             base.OnStopped();

             Console.WriteLine("服务器已停止");

         }  



    }

}
View Code

MySession.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;



using SuperSocket.SocketBase;

using SuperSocket.SocketBase.Protocol;



namespace ConsoleApp

{

    /// <summary>  

    /// 自定义连接类MySession,继承AppSession,并传入到AppSession  

    /// </summary>  

    public class MySession : AppSession<MySession>

    {

        /// <summary>  

        /// 新连接  

        /// </summary>  

        protected override void OnSessionStarted()

        {

            Console.WriteLine(this.LocalEndPoint.Address.ToString());   //输出客户端IP地址  

            this.Send("\r\nHello User");  

        }



        /// <summary>  

        /// 未知的Command  

        /// </summary>  

        /// <param name="requestInfo"></param>  

        protected override void HandleUnknownRequest(StringRequestInfo requestInfo)

        {

            this.Send("\r\n未知的命令");

        }



        /// <summary>  

        /// 捕捉异常并输出  

        /// </summary>  

        /// <param name="e"></param>  

        protected override void HandleException(Exception e)

        {

            this.Send("\r\n异常: {0}", e.Message);

        }



        /// <summary>  

        /// 连接关闭  

        /// </summary>  

        /// <param name="reason"></param>  

        protected override void OnSessionClosed(CloseReason reason)

        {

            base.OnSessionClosed(reason);

        }  



    }

}
View Code

Program.cs

注:不好意思,这个里面有一些没用的代码,留着是因为以后可能要用到

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;



using SuperSocket.SocketBase;

using SuperSocket.SocketBase.Protocol;

using SuperSocket.SocketBase.Command;

using MyAppSession;

using ConsoleApp;

using System.Net;

using System.Net.Sockets;

using SuperSocket.SocketEngine;



namespace ConsoleApp

{

    class Program

    {

        private static byte[] data = new byte[1024];

        static void Main(string[] args)

        {

            Console.WriteLine("Press any key to start the server!");



            Console.ReadKey();

            Console.WriteLine();



            //var appServer = new AppServer();

            var appServer = new MyServer();



            //Setup the appServer

            if (!appServer.Setup(2012)) //Setup with listening port 建立一个服务器,端口是2012

            {

                Console.WriteLine("Failed to setup!");

                Console.ReadKey();

                return;

            }



            Console.WriteLine();



            //Try to start the appServer

            if (!appServer.Start()) //服务器启动

            {

                Console.WriteLine("Failed to start!");

                Console.ReadKey();

                return;

            }



            #region 客户端连接成功之后进行的操作

            #region 1.处理连接

            appServer.NewSessionConnected += new SessionHandler<MySession>(appServer_NewSessionConnected);

            #endregion 1.处理连接



            //#region 2.处理请求

            ////appServer.NewRequestReceived += new RequestHandler<AppSession, StringRequestInfo>(appServer_NewRequestReceived);

            //appServer.NewRequestReceived += new RequestHandler<AppSession, StringRequestInfo>(appServer_NewRequestReceived);

            //#endregion 2.处理请求

            //appServer.NewRequestReceived += new RequestHandler<MySession, StringRequestInfo>(ExecuteCommand);

            #endregion 客户端连接成功之后进行的操作



            Console.WriteLine("The server started successfully, press key 'q' to stop it!");



            #region 测试命令添加

            //RegisterCommands();

            #endregion 测试命令添加



            while (true)

            {

                var str = Console.ReadLine();

                if (str.ToLower().Equals("exit"))

                {

                    break;

                }  

            }

            Console.WriteLine();  



            //while (Console.ReadKey().KeyChar != 'q')

            //{

            //    Console.WriteLine();

            //    continue;

            //}



            ////Stop the appServer

            //appServer.Stop();   //服务器关闭



            Console.WriteLine("服务已停止,按任意键退出!");

            Console.ReadKey();

        }

        #region 事件

        /// <summary>

        /// 连接事件

        /// </summary>

        /// <param name="session"></param>

        static void appServer_NewSessionConnected(MySession session)

        {

            session.Send("Welcome to SuperSocket Telnet Server");

        }

        /// <summary>

        /// 请求

        /// </summary>

        /// <param name="session"></param>

        /// <param name="requestInfo"></param>

        static void appServer_NewRequestReceived(AppSession session, StringRequestInfo requestInfo)

        {

            switch (requestInfo.Key.ToUpper())

            {

                case ("ECHO"):

                    session.Send(requestInfo.Body);

                    break;



                case ("ADD"):   //加法

                    session.Send(requestInfo.Parameters.Select(p => Convert.ToInt32(p)).Sum().ToString());

                    break;



                case ("MULT"):  //乘法



                    var result = 1;



                    foreach (var factor in requestInfo.Parameters.Select(p => Convert.ToInt32(p)))

                    {

                        result *= factor;

                    }



                    session.Send(result.ToString());

                    break;

            }

        }

        #endregion 事件



        //#region 方法

        ///// <summary>

        ///// 输出输入内容

        ///// </summary>

        //public class ECHO : CommandBase<AppSession, StringRequestInfo>

        //{

        //    public override string Name

        //    {

        //        get { return "01"; }

        //    }

        //    public override void ExecuteCommand(AppSession session, StringRequestInfo requestInfo)

        //    {

        //        session.Send(requestInfo.Body);

        //    }

        //}

        ///// <summary>

        ///// 定义一个名为"ADD"的类去处理Key为"ADD"的请求

        ///// </summary>

        //public class ADD : CommandBase<AppSession, StringRequestInfo>

        //{

        //    public override string Name

        //    {

        //        get { return "02"; }

        //    }

        //    public override void ExecuteCommand(AppSession session, StringRequestInfo requestInfo)

        //    {

        //        session.Send(requestInfo.Parameters.Select(p => Convert.ToInt32(p)).Sum().ToString());

        //    }

        //}

        ///// <summary>

        ///// 定义一个名为"MULT"的类去处理Key为"MULT"的请求

        ///// </summary>

        //public class MULT : CommandBase<AppSession, StringRequestInfo>

        //{

        //    public override string Name

        //    {

        //        get { return "03"; }

        //    }

        //    public override void ExecuteCommand(AppSession session, StringRequestInfo requestInfo)

        //    {

        //        var result = 1;



        //        foreach (var factor in requestInfo.Parameters.Select(p => Convert.ToInt32(p)))

        //        {

        //            result *= factor;

        //        }



        //        session.Send(result.ToString());

        //    }

        //}

        //#endregion 方法



        #region 使用SuperSocket自带事件处理方式

        private static Dictionary<string, ControlCommand> m_CommandHandlers = new Dictionary<string, ControlCommand>(StringComparer.OrdinalIgnoreCase);



        private static void AddCommand(string name, string description, Func<IBootstrap, string[], bool> handler)

        {

            var command = new ControlCommand

            {

                Name = name,

                Description = description,

                Handler = handler

            };



            m_CommandHandlers.Add(command.Name, command);

        }



        private static void RegisterCommands()

        {

            AddCommand("List", "List all server instances", ListCommand);

            AddCommand("Start", "Start a server instance: Start {ServerName}", StartCommand);

            AddCommand("Stop", "Stop a server instance: Stop {ServerName}", StopCommand);

        }



        static bool ListCommand(IBootstrap bootstrap, string[] arguments)

        {

            foreach (var s in bootstrap.AppServers)

            {

                var processInfo = s as IProcessServer;



                if (processInfo != null && processInfo.ProcessId > 0)

                    Console.WriteLine("{0}[PID:{1}] - {2}", s.Name, processInfo.ProcessId, s.State);

                else

                    Console.WriteLine("{0} - {1}", s.Name, s.State);

            }



            return false;

        }



        static bool StopCommand(IBootstrap bootstrap, string[] arguments)

        {

            var name = arguments[1];



            if (string.IsNullOrEmpty(name))

            {

                Console.WriteLine("Server name is required!");

                return false;

            }



            var server = bootstrap.AppServers.FirstOrDefault(s => s.Name.Equals(name, StringComparison.OrdinalIgnoreCase));



            if (server == null)

            {

                Console.WriteLine("The server was not found!");

                return false;

            }



            server.Stop();



            return true;

        }



        static bool StartCommand(IBootstrap bootstrap, string[] arguments)

        {

            var name = arguments[1];



            if (string.IsNullOrEmpty(name))

            {

                Console.WriteLine("Server name is required!");

                return false;

            }



            var server = bootstrap.AppServers.FirstOrDefault(s => s.Name.Equals(name, StringComparison.OrdinalIgnoreCase));



            if (server == null)

            {

                Console.WriteLine("The server was not found!");

                return false;

            }



            server.Start();



            return true;

        }



        static void ReadConsoleCommand(IBootstrap bootstrap)

        {

            var line = Console.ReadLine();



            if (string.IsNullOrEmpty(line))

            {

                ReadConsoleCommand(bootstrap);

                return;

            }



            if ("quit".Equals(line, StringComparison.OrdinalIgnoreCase))

                return;



            var cmdArray = line.Split(' ');



            ControlCommand cmd;



            if (!m_CommandHandlers.TryGetValue(cmdArray[0], out cmd))

            {

                Console.WriteLine("Unknown command");

                ReadConsoleCommand(bootstrap);

                return;

            }



            try

            {

                if (cmd.Handler(bootstrap, cmdArray))

                    Console.WriteLine("Ok");

            }

            catch (Exception e)

            {

                Console.WriteLine("Failed. " + e.Message + Environment.NewLine + e.StackTrace);

            }



            ReadConsoleCommand(bootstrap);

        }

        #endregion 使用SuperSocket自带事件处理方式



    }

}
View Code

效果:

服务器端:

  SuperSocket学习笔记(一)

telnet端:命令是01

  SuperSocket学习笔记(一)

注意:如果不使用telnet,则记得在客户端发送命令的末尾加上"\r\n",因为SuperSocket默认的协议是命令行协议

这是一个很简单的例子,虽然只是一小步,但也给我带来了前进的动力,自勉一下,呵呵!!!

 

 

 

 

 

 

你可能感兴趣的:(socket)