SuperSocket学习笔记(一)
这是根据我自己学习的经历整理出来的,如有不对之处,还请多多指教!
安装并启动Telnet
学习方法:
QuickStrart + 文档
参考资料:
下面是一个例子的主要源码:
最终形成的目录:(Config文件夹中log4net.config文件来自SupertSocket源码)
文件源码:
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
效果:
服务器端:
telnet端:命令是01
注意:如果不使用telnet,则记得在客户端发送命令的末尾加上”\r\n”,因为SuperSocket默认的协议是命令行协议
这是一个很简单的例子,虽然只是一小步,但也给我带来了前进的动力,自勉一下,呵呵!!!