Net6/SuperSocket2.0課程1,一個Telnet示例

十年河東,十年河西,莫欺少年窮

學無止境,精益求精

1、新建控制檯程序並引入包

dotnet add package SuperSocket.Server

 2、書寫代碼

using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using SuperSocket;
using SuperSocket.ProtoBase;

namespace MySupersocket // Note: actual namespace depends on the project name.
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            var Listeners = new List<ListenOptions>() {  new ListenOptions
        {
            Ip = "Any",
            Port = 4040
        }, new ListenOptions
        {
            Ip = "Any",
            Port = 8040
        }};
            var host = SuperSocketHostBuilder
     .Create<StringPackageInfo, CommandLinePipelineFilter>().UsePackageHandler(async (session, package) =>
     {
         var result = 0;
         //接收的包 類型爲StringPackageInfo 也就是字符串
         Console.WriteLine($"package如下:");
         Console.WriteLine(JsonConvert.SerializeObject(package));
         //session 可以理解爲客戶端的某個連接
         Console.WriteLine($"session如下:");
         //客戶端關閉連接原因
         Console.WriteLine("ChannelCloseReason:" + session.Channel.CloseReason); 
         //客戶端最後活躍時間
         Console.WriteLine("LastActiveTime:" + session.LastActiveTime);
         //服務器偵聽的IP+端口,也就是偵聽地址
         Console.WriteLine("LocalEndPoint:" + session.LocalEndPoint);
         //客戶端IP+端口,也就是客戶端地址
         Console.WriteLine("RemoteEndPoint:" + session.RemoteEndPoint);
         //當前客戶端連接數量
         Console.WriteLine("SessionCount:" + session.Server.SessionCount);
         //當前服務器偵聽的狀態
         Console.WriteLine("ServerState:" + session.Server.State);
         //當前鏈接的唯一標識
         Console.WriteLine("SessionID:" + session.SessionID);
         //當前鏈接的開始時間
         Console.WriteLine("StartTime:" + session.StartTime);
         //當前鏈接的狀態
         Console.WriteLine("State:" + session.State);
         switch (package.Key.ToUpper())
         {
             case ("ADD"):
                 result = package.Parameters
                     .Select(p => int.Parse(p))
                     .Sum();
                 break;

             case ("SUB"):
                 result = package.Parameters
                     .Select(p => int.Parse(p))
                     .Aggregate((x, y) => x - y);
                 break;

             case ("MULT"):
                 result = package.Parameters
                     .Select(p => int.Parse(p))
                     .Aggregate((x, y) => x * y);
                 break;
         }
         // \r\n 爲鍵盤迴車換行
         await session.SendAsync(Encoding.UTF8.GetBytes(result.ToString() + "\r\n"));
     }).ConfigureSuperSocket(options =>
     {
         options.Name = "Echo Server";
         options.Listeners = Listeners;
     }).ConfigureLogging((hostCtx, loggingBuilder) =>
     {
         loggingBuilder.AddConsole();
     }).Build();
            await host.RunAsync();
            Console.Read();
        }
    }
}
View Code

3、使用telnet測試

telnet 127.0.0.1 8040

NetCore輸出

 4、概念解讀

4.1、Package Type(包類型/內置行協議)

TextPackageInfo

 包類型 TextPackageInfo(SuperSocket.ProtoBase.TextPackageInfo,SuperSocket.ProtoBase) 是在 SuperSocket 中定義的最簡單的數據包。它代表這類型的包僅包含一個字符串。

namespace SuperSocket.ProtoBase
{
    public class TextPackageInfo
    {
        public string Text { get; set; }

        public override string ToString()
        {
            return Text;
        }
    }
}

StringPackageInfo

StringPackageInfo是簡單的包括鍵值和body的數據結構,一些內置Filter默認將過濾好的數據解析爲StringPackageInfo類。StringPackageInfo類使用了一個空格來分割請求key和參數

namespace SuperSocket.ProtoBase
{
    public class StringPackageInfo : IKeyedPackageInfo<string>, IStringPackage
    {
        public string Key { get; set; }

        public string Body { get; set; }

        public string[] Parameters { get; set; }
    }
}

4.2、AppSession

AppSession

根據官方描述,AppSession代表一個和客戶端的邏輯連接,基於連接的操作應該定於在該類之中。你可以用該類的實例發送數據到客戶端,接收客戶端發送的數據或者關閉連接。

對於實現固定頭協議來說,AppSession不是必須的,但是站在應用服務器的角度來說,一個AppSession對象就是一個客戶端連接,該客戶端起碼會含有標識自己的信息,這是應用服務器所需要的。

4.3、PipelineFilter 行協議過濾器

SuperSocket 提供了這些 PipelineFilter 模版:

TerminatorPipelineFilter (SuperSocket.ProtoBase.TerminatorPipelineFilter, SuperSocket.ProtoBase)
TerminatorTextPipelineFilter(SuperSocket.ProtoBase.TerminatorTextPipelineFilter, SuperSocket.ProtoBase)
LinePipelineFilter (SuperSocket.ProtoBase.LinePipelineFilter, SuperSocket.ProtoBase)
CommandLinePipelineFilter (SuperSocket.ProtoBase.CommandLinePipelineFilter, SuperSocket.ProtoBase)  
BeginEndMarkPipelineFilter (SuperSocket.ProtoBase.BeginEndMarkPipelineFilter, SuperSocket.ProtoBase) 
FixedSizePipelineFilter (SuperSocket.ProtoBase.FixedSizePipelineFilter, SuperSocket.ProtoBase)  
FixedHeaderPipelineFilter (SuperSocket.ProtoBase.FixedHeaderPipelineFilter, SuperSocket.ProtoBase) 

1、TerminatorPipelineFilter 終止符過濾器(過濾解析指定終止符之前的數據,默認解析成StringPackageInfo類)

2、TerminatorTextPipelineFilter 終止符文本管道過濾器(過濾解析指定終止符之前的數據,默認解析成TextPackageInfo類)

3、LinePipelineFilter 管路過濾器(最普通的過濾器,除了命令行限制,其他無限制,默認解析成TextPackageInfo類)

4、CommandLinePipelineFilter 命令行管道過濾器(最普通的過濾器,除了命令行限制,其他無限制,默認解析成StringPackageInfo類)

5、BeginEndMarkPipelineFilter 有固定開始結束標記管道過濾器(根據開始和結束符過濾有效數據,默認解析成StringPackageInfo類)

6、FixedSizePipelineFilter 固定長度過濾器(只解析指定長度的數據,當數據長度小於指定長度時,會報錯並斷開連接重連,默認解析成StringPackageInfo類)

7、FixedHeaderPipelineFilter 固定開頭(長度)管道過濾器(通過指定數據包開頭長度,重寫GetBodyLengthFromHeader方法,從開頭數據包中獲取有效數據包的長度,默認解析成StringPackageInfo類)

 

 參考博客:https://blog.csdn.net/weixin_33277597/article/details/122051837

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章