• 【C#】SuperSocket配置启动UDP服务器


    SuperSocket配置UDP服务器

    零、需求

    • 两个设备局域网联机,需要用广播自动搜寻,而SuperSocket1.6的默认AppServer使用的是TCP,但只有UDP才支持广播。

    一、解决

    • 推荐小白使用方案二,简单快捷。

    1. 方案一:可以通过配置 “App.config” 文件,再使用 “BootstrapFactory” 来启动UDP服务器。(这个是参考了C#SuperSocket的搭建--通过配置启动的)

    • 编写自己的 “Session” 类,我这边随便写写
    using SuperSocket.SocketBase;
    using SuperSocket.SocketBase.Protocol;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace SuperSocketTest.src.Service.UDPServer
    {
            //这边权限要public,不然在接下来的命令类那边是会报错的
            public class MySession : AppSession<MySession>
            {
                    protected override void OnSessionStarted()
                    {
                            //连接后发送欢迎信息
                            this.Send("Welcome to SuperSocket Telnet Server");
                    }
    
                    protected override void HandleUnknownRequest(StringRequestInfo requestInfo)
                    {
                            //无法解析命令提示未知命令
                            this.Send("Unknow request");
                    }
    
                    protected override void HandleException(Exception e)
                    {
                            //程序异常信息
                            this.Send("Application error: {0}", e.Message);
                    }
    
                    protected override void OnSessionClosed(CloseReason reason)
                    {
                            //连接被关闭时
                            base.OnSessionClosed(reason);
                    }
            }
    }
    
    • 接着按自己需求定义自己APPServer,这边我也随便写写(自定义的AppServer,在继承AppServer是的Session泛型,记得要更改为我们自定义的Session,这边我的是MySession)
    using SuperSocket.SocketBase;
    using SuperSocket.SocketBase.Config;
    using SuperSocket.SocketBase.Protocol;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace SuperSocketTest.src.Service.UDPServer
    {
            class MyServer : AppServer<MySession>
            {
                    //这边Base里留空就是默认的命令行编码和用空格分隔
                    //这边我把命令与参数之间的分隔符改为“:”,把参数之间的分隔符改为“,”
                    public MyServer()
                            : base(new CommandLineReceiveFilterFactory(Encoding.Default, new BasicRequestInfoParser(":", ",")))
                    {
                    }
    
                    protected override bool Setup(IRootConfig rootConfig, IServerConfig config)
                    {
                            return base.Setup(rootConfig, config);
                    }
    
                    protected override void OnStopped()
                    {
                            base.OnStopped();
                    }
            }
    }
    
    • SuperSocket 中的命令设计出来是为了处理来自客户端的请求的, 它在业务逻辑处理之中起到了很重要的作用。所以我们写一个自己的命令类。(后面好像处理不了,我也不知道怎么回事)
    using SuperSocket.SocketBase.Command;
    using SuperSocket.SocketBase.Protocol;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace SuperSocketTest.src.Service.UDPServer
    {
            //这边权限要public才能被扫描到,CommandBase的第一个填刚刚自己创建的MySession
            public class MyCommand : CommandBase<MySession, StringRequestInfo>
            {
                    public override string Name
                    {
                            get
                            {
                                    //调用命令的名字,如果不覆盖,默认是类名
                                    return "001";
                            }
                    }
    
                    public override void ExecuteCommand(MySession session, StringRequestInfo requestInfo)
                    {
                            //向客户端返回信息,已接受到命令
                            session.Send("Hello,I'm UDP server! The parameter you send is " + requestInfo.Body);
                    }
            }
    }
    
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <!--下面configSections这项一定是放在configuration里的第一个,不然会报错-->
      <configSections>
        <section name="superSocket"
             type="SuperSocket.SocketEngine.Configuration.SocketServiceConfig, SuperSocket.SocketEngine" />
      </configSections>
      <superSocket>
        <servers>
          <!--serverType中,逗号左边的是你自定义的server在项目中的位置(命名空间加类名),逗号右边是项目名(命名空间的第一个.之前的),ip就是服务器ip(Any代表本机),port端口号,mode:Tcp或者Udp模式-->
          <server name="SSTUDP"
              serverType="SuperSocketTest.src.Service.UDPServer.MyServer,SuperSocketTest"
              ip="Any" port="2020" mode="Udp">
          </server>
        </servers>
      </superSocket>
      <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
      </startup>
    </configuration>
    
    • 最后,主程序中调用Bootstrap启动服务器。
    using SuperSocket.SocketBase;
    using SuperSocket.SocketEngine;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace SuperSocketTest
    {
            class Program
            {
                    static void Main(string[] args)
                    {
                            Console.WriteLine("按任意键以启动服务器!");
    
                            Console.ReadKey();
                            Console.WriteLine();
       
                            var bootstrap = BootstrapFactory.CreateBootstrap();
    
                            if (!bootstrap.Initialize())
                            {
                                    Console.WriteLine("初始化失败!请检查配置文件!");
                                    Console.ReadKey();
                                    return;
                            }
    
                            var result = bootstrap.Start();
    
                            Console.WriteLine("启动结果: {0}!", result);
    
                            if (result == StartResult.Failed)
                            {
                                    Console.WriteLine("启动失败!");
                                    Console.ReadKey();
                                    return;
                            }
    
                            Console.WriteLine("按 ‘q’ 键停止服务器。");
    
                            while (Console.ReadKey().KeyChar != 'q')
                            {
                                    Console.WriteLine();
                                    continue;
                            }
    
                            Console.WriteLine();
    
                            //关闭服务器
                            bootstrap.Stop();
    
                            Console.WriteLine("服务器已停止!");
                            Console.ReadKey();
                             
                    }
            }
    }
    
    • 结果:
      启动成功
      -- 成功,这边使用的自定义的命令行格式!

    2. 方案二:通过代码的方式启动,这样简单些,但是文档中没有给出方法,在查阅源码后发现,设置启动模式可以在“AppServer”类的“Setup”方法中设置。

    using SuperSocket.SocketBase;
    using SuperSocket.SocketBase.Config;
    using SuperSocket.SocketBase.Protocol;
    using SuperSocket.SocketEngine;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace SuperSocketTest
    {
            class Program
            {
                    /// <summary>
                    /// 客户端计数器
                    /// </summary>
                    static int clientCount = 0;
    
                    static void Main(string[] args)
                    {
                            Console.WriteLine("按任意键以启动服务器!");
                            Console.ReadKey();
                            Console.WriteLine();
    
                            var appServer = new AppServer();
    
                            //在这设置服务器模式,更多属性请参阅官方文档
                            if (!appServer.Setup(new ServerConfig
                                {
                                    Ip = "Any",
                                    Port = 2020,
                                    Mode = SocketMode.Udp
                                }))//配置服务器
                            {
                                    Console.WriteLine("配置服务器失败!");
                                    Console.ReadKey();
                                    return;
                            }
    
                            Console.WriteLine();
                            //尝试启动服务器
                            if (!appServer.Start())
                            {
                                    Console.WriteLine("启动失败!");
                                    Console.ReadKey();
                                    return;
                            }
                            Console.WriteLine("服务器启动成功,按 ‘q’ 键停止服务器!");
                            
                            //注册新连接
                            appServer.NewSessionConnected += new SessionHandler<AppSession>(appServer_NewSessionConnected);
                            //注册命令响应
                            appServer.NewRequestReceived += new RequestHandler<AppSession, StringRequestInfo>(appServer_NewRequestReceived);
                           
                            while (Console.ReadKey().KeyChar != 'q')
                            {
                                    Console.WriteLine();
                                    continue;
                            }
                            //停止服务器
                            appServer.Stop();
                            Console.WriteLine("服务器已停止!");
                            Console.ReadKey();
                    }
    
                    /// <summary>
                    /// 处理第一次连接
                    /// </summary>
                    /// <param name="session">socket会话</param>
                    private static void appServer_NewSessionConnected(AppSession session)
                    {
                            clientCount++;
                            session.Send("Hello,you are the " + clientCount + "th connected client!");
                    }
    
                    /// <summary>
                    /// 处理命令
                    /// </summary>
                    /// <param name="session">socket会话</param>
                    /// <param name="requestInfo">请求的内容,详见官方文档</param>
                    private static void appServer_NewRequestReceived(AppSession session, StringRequestInfo requestInfo)
                    {
                            switch (requestInfo.Key.ToUpper())
                            {
                                    case ("001")://同样添加一条命令,更多命令的使用请查阅文档
                                            session.Send("Hello,I'm UDP server! The parameter you send is " + requestInfo.Body);
                                            break;
                            }
    
                    }
            }
    }
    
    • 结果:
      结果
      -- 成功!

    二、总结

    • 可以通过配置和代码来启动服务器。
    • 代码在AppServer.Setup函数下配置。
    • 文件配置在App.config文件里配置,再通过Bootstrap启动服务器。
    • 对于TCP方式同样适用,只需要设置mode的值为Tcp即可。
    • SuperSocket很棒!怎么三年前没有发现这个宝藏呢!
    • UDP测试 V1软件:UDP收发器 Gitee

    谢谢支持

  • 相关阅读:
    Hibernate 与 mybatis 区别
    Struts2 核心流程
    java 面试 -- 4
    无线电日记 2
    ham 无线电笔记
    Our Deepest Fear
    随笔
    GSM学习笔记
    网络时代的悲哀:微软百科全书
    [转载]arm交叉编译器gnueabi、none-eabi、arm-eabi、gnueabihf、gnueabi区别
  • 原文地址:https://www.cnblogs.com/minuy/p/13734908.html
Copyright © 2020-2023  润新知