码迷,mamicode.com
首页 > 其他好文 > 详细

SuperSocket学习笔记(一)

时间:2014-04-30 16:22:05      阅读:1206      评论:0      收藏:0      [点我收藏+]

标签:des   com   http   blog   style   class   div   img   code   c   log   

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

SuperSocket源码下载  

SuperSocket文档

安装并启动Telnet

学习方法:

  QuickStrart + 文档

参考资料:

 

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

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

bubuko.com,布布扣

文件源码:

app.config

bubuko.com,布布扣
<?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

bubuko.com,布布扣
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

bubuko.com,布布扣
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

bubuko.com,布布扣
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

bubuko.com,布布扣
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

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

bubuko.com,布布扣
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

效果:

服务器端:

  bubuko.com,布布扣

telnet端:命令是01

  bubuko.com,布布扣

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

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

 

 

 

 

 

 

SuperSocket学习笔记(一),布布扣,bubuko.com

SuperSocket学习笔记(一)

标签:des   com   http   blog   style   class   div   img   code   c   log   

原文地址:http://www.cnblogs.com/zhizihuakai/p/3699316.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!