zoukankan      html  css  js  c++  java
  • SuperSocket服务端与客户端搭建

    本文记录使用SuperSocket搭建Socket服务端,然后搭建客户端与之通信

    环境:.Net 4.5

    一、先说服务端

    创建一个控制台SuperSocketServer,创建会话类:MyServerSession

    public   class MyServerSession:AppSession<MyServerSession>
        {
            public override void Send(string message)
            {
                Console.WriteLine("发送消息:"+message);
                base.Send(message);
            }
            protected override void OnSessionStarted()
            {
                Console.WriteLine("Session已启动" );
                base.OnSessionStarted();
            }
            protected override void OnInit()
            {
                this.Charset = Encoding.GetEncoding("gb2312");
                base.OnInit();
            }
    
           protected override void HandleUnknownRequest(StringRequestInfo requestInfo)
            {
                Console.WriteLine("未知请求");
                base.HandleUnknownRequest(requestInfo);
            }
        }

    分别表示4个状态和动作,一看就明白。

    然后创建服务类:MyServer

    public class MyServer:AppServer<MyServerSession>
      {
          protected override bool Setup(IRootConfig rootConfig, IServerConfig config)
          {
              Console.WriteLine("正在准备配置文件");
              return base.Setup(rootConfig, config);
          }
          protected override void OnStarted()
          {
              Console.WriteLine("服务已启动");
              base.OnStarted();
          }
          protected override void OnStopped()
          {
              Console.WriteLine("服务已停止");
              base.OnStopped();
          }
          protected override void OnNewSessionConnected(MyServerSession session)
          {
              Console.WriteLine("新链接进入:" + session.LocalEndPoint.Address.ToString() +":"+ session.RemoteEndPoint.Port + "(" + session.SessionID + ")" + ",时间:" + DateTime.Now);
              base.OnNewSessionConnected(session);
          }
          protected override void OnSessionClosed(MyServerSession session, CloseReason reason)
          {
              Console.WriteLine("链接关闭:" + session.LocalEndPoint.Address.ToString() + ":" + session.RemoteEndPoint.Port + "(" + session.SessionID + ")" + ",时间:" + DateTime.Now);
              base.OnSessionClosed(session, reason);
          }
      }

    表示服务器的4个状态,这些状态可以根据业务进行扩展

    再创建命令类:ECHO执行客户端的命令

    public  class ECHO: CommandBase<MyServerSession, StringRequestInfo>
         {
             public override void ExecuteCommand(MyServerSession session, StringRequestInfo requestInfo)
             {
                 if (requestInfo.Parameters.Length < 2)
                     return;
                 string cmd = requestInfo.Parameters[0];
                 switch (cmd)
                 {
                     case "heart":// heart 2
                         session.Send("ok");
                         break;
                     case "hello":// hello 2
                         session.Send("你说:"+ requestInfo.Parameters[1]);
                         break;
                     case "login":// login 我 000 000
                         string userID = requestInfo.Parameters[1];
                         Console.WriteLine(userID + "登录成功");
                         break;
                     case "sendto"://sendto 我ID 他ID 内容
                         rev.Send(requestInfo.Parameters[3]);
                         Console.WriteLine(string.Format("{0}对{1}说:{2}", requestInfo.Parameters[1],requestInfo.Parameters[2], requestInfo.Parameters[3]));
                         break;
                     default:
                         break;
                 }
                 if (requestInfo.Parameters[0] == "all")
                 {
                     var sessions = session.AppServer.GetAllSessions();
                     foreach (var item in sessions)
                     {
                         item.Send(requestInfo.Body);
                     }
                 }
    
                //根据参数个数或者其他条件判断,来进行一些自己的操作
                 //if (requestInfo.Parameters.Length == 2)
                 //{
                 //    Console.WriteLine("调用成功");
                 //    session.Send(string.Format("{0}:{1},已经成功接收到你的请求\r\n", session.RemoteEndPoint.Address, session.RemoteEndPoint.Port));
                 //}
                 //else
                 //{
                 //    session.Send("参数不正确\r\n");
                 //}
                 //session.Send(requestInfo.Body);
             }
    
         }

    这个类里面列举了执行动作判断,消息群发,一对一发,当然叶可以一对多

    最后是启动服务main

    static void Main(string[] args)
    {
         IBootstrap bootstrap = BootstrapFactory.CreateBootstrap();
         if (!bootstrap.Initialize())
         {
             Console.WriteLine(DateTime.Now + ":Socket初始化失败\r\n");
             return;
         }
    
        var result = bootstrap.Start();
         foreach (var server in bootstrap.AppServers)
         {
             if (server.State == ServerState.Running)
             {
                 Console.WriteLine(DateTime.Now + ":serverName为:" + server.Name + "Socket运行中\r\n");
                 Console.Read();
             }
             else
             {
                 Console.WriteLine(DateTime.Now + ":serverName为:" + server.Name + "Socket启动失败\r\n");
             }
         }
    }

    也是一看就能明白,还有配置文件:

    <configuration>
    <configSections>
    <!--log 日志记录-->
    <section name="log4net" type="System.Configuration.IgnoreSectionHandler" />
    <!--SocketEngine-->
    <section name="superSocket" type="SuperSocket.SocketEngine.Configuration.SocketServiceConfig, SuperSocket.SocketEngine" />
    </configSections>
         <!--配置SocketServer路径-->
         <superSocket>
             <servers>
                 <server name="MySocket" textEncoding="gb2312"
                         serverType="SuperSocketServer.MyServer, SuperSocketServer"
                        ip="Any" port="2018" maxConnectionNumber="100">
                 </server>
             </servers>
         </superSocket>
    
        <startup>
             <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
         </startup>
    </configuration>

    全部的引用是这几个:

    image


    二、再说客户端

    目前代码较为简单,实现了心跳与断线重连

    class Program
    {
         private static AsyncTcpSession client;
         static System.Timers.Timer timer = null;
         private int port = 2018;
    
        static void Main(string[] args)
         {
             new Program().Link();
             string input = Console.ReadLine();
             while (input != "exit"&& !string.IsNullOrEmpty(input))
             {
                 if (client != null && client.IsConnected)
                 {
                     var msg = System.Text.Encoding.Default.GetBytes("echo hello " + input + "\r\n");
                     client.Send(msg,0, msg.Length);
                     input = Console.ReadLine();
                 }
    
            }
         }
         private void Link()
         {
             client = new AsyncTcpSession();
             client.Connected += OnClientConnected;
             client.Error += OnClientError;
             client.Closed += OnClientClosed;
             // 收到服务器数据事件
             client.DataReceived += client_DataReceived;
    
            //每10s发送一次心跳或尝试一次重连
             timer = new System.Timers.Timer(10000);
             timer.Elapsed += new System.Timers.ElapsedEventHandler((s, x) =>
             {
                 //心跳包
                 if (client.IsConnected)
                 {
                     var heartMsg = System.Text.Encoding.Default.GetBytes("echo heart 2\r\n");
                     client.Send(heartMsg,0, heartMsg.Length);
                 }
                 //断线重连
                 else if (!client.IsConnected)
                 {
                     client.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), port));
                 }
             });
             timer.Enabled = true;
             timer.Start();
    
        }
         private void OnClientConnected(object sender, EventArgs e)
         {
             Console.WriteLine("已连接" + '\n');
         }
         private void OnClientClosed(object sender, EventArgs e)
         {
             Console.WriteLine("已断开" + '\n');
         }
         private void OnClientError(object sender, ErrorEventArgs e)
         {
             Console.WriteLine($"错误:{e.Exception.Message}" + '\n');
         }
         void client_DataReceived(object sender, DataEventArgs e)
         {
             string msg = Encoding.Default.GetString(e.Data);
             Console.WriteLine(msg.Trim('\0'));
         }
    }

    引用如下:

    image

    控制台版代码下载,压缩包里面带了tcptool可以不用客户端测试,记得每个命令完了要敲回车

    Winform版代码下载

  • 相关阅读:
    出错处理函数abort、exit、atexit、strerror. . .
    linux查询系统信息命令
    [转载]比google和百度强十倍的搜索类网站
    陶  朱  商  经
    ip的划分,超详细.【网管常识】
    linux的hostname修改详解
    勤于寻找谈话资料
    Windows常用命令集
    C语言中printf格式
    How to disable SELinux
  • 原文地址:https://www.cnblogs.com/madyina/p/15733368.html
Copyright © 2011-2022 走看看