首页 > 编程语言 >C# 使用SuperSocket的FixedHeaderReceiveFilter进行通信

C# 使用SuperSocket的FixedHeaderReceiveFilter进行通信

时间:2024-10-28 14:00:48浏览次数:4  
标签:SuperSocket appServer C# FixedHeaderReceiveFilter int new byte public 字节

一、服务端
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { MyServer appServer = new MyServer(); var se = new SuperSocket.SocketBase.Config.ServerConfig(); se.TextEncoding = "Unicode";// System.Text.Encoding. se.TextEncoding = "gbk";// System.Text.Encoding. se.Ip = "127.0.0.1"; se.Port = 2020; se.Mode = SocketMode.Tcp; if (!appServer.Setup(se)) //Setup with listening port { 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; } //appServer.NewSessionConnected += appServer_NewSessionConnected; //appServer.SessionClosed += appServer_SessionClosed; appServer.NewRequestReceived += appServer_NewRequestReceived; } static void appServer_NewRequestReceived(MySession session, BinaryRequestInfo requestInfo) { string key = requestInfo.Key; switch (key) { case "1": Console.WriteLine("Get message from " + session.RemoteEndPoint.ToString() + ":" + System.Text.Encoding.UTF8.GetString(requestInfo.Body)); break; case "2": Console.WriteLine("Get image"); break; default: Console.WriteLine("Get unknown message."); break; } } }
 public class MyServer : AppServer<MySession, BinaryRequestInfo>
    {
        public MyServer()
            : base(new DefaultReceiveFilterFactory<MyReceiveFilter, BinaryRequestInfo>()) //使用默认的接受过滤器工厂 (DefaultReceiveFilterFactory)
        {
        }
    }

    public class MySession : AppSession<MySession, BinaryRequestInfo>
    {
    }
public class MyReceiveFilter : FixedHeaderReceiveFilter<BinaryRequestInfo>
    {

        public MyReceiveFilter()
            : base(10)//消息头部长度
        { }
        /// <summary>
        ///
        /// </summary>
        /// <param name="header">*byte[] header * 缓存的数据,这个并不是单纯只包含协议头的数据,有时候tcp协议长度为409600,很多</param>
        /// <param name="offset">头部数据从 缓存的数据 中开始的索引,一般为0.(tcp协议有可能从405504之类的一个很大数据开始)</param>
        /// <param name="length">这个length和base(10)中的参数相等</param>
        /// <returns></returns>
        protected override int GetBodyLengthFromHeader(byte[] header, int offset, int length)
        {
            return GetBodyLengthFromHeader(header, offset, length, 6, 4);//6表示第几个字节开始表示长度.4:由于是int来表示长度,int占用4个字节
        }
        protected override BinaryRequestInfo ResolveRequestInfo(ArraySegment<byte> header, byte[] bodyBuffer, int offset, int length)
        {

            byte[] body = new byte[length];
            Array.Copy(bodyBuffer, offset, body, 0, length);

            Int16 type = BitConverter.ToInt16(header.Array, 4);

            BinaryRequestInfo r = new BinaryRequestInfo(type.ToString(), body);
            return r;

            //以下的代码,不解析body,全部返给上一层
            //byte[] h = header.ToArray();
            //byte[] full = new byte[h.Count()+length];
            //Array.Copy(h, full, h.Count());
            //Array.Copy(body, 0, full, h.Count(), body.Length );
            //BinaryRequestInfo r = new BinaryRequestInfo("",full);
            //return r;

        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="header">需要解析的数据</param>
        /// <param name="offset">头部数据从header中开始的索引,一般为0,也可能不是0</param>
        /// <param name="length">这个length和base(10)中的参数相等</param>
        /// <param name="lenStartIndex">表示长度的字节从第几个开始</param>
        /// <param name="lenBytesCount">几个字节来表示长度:4个字节=int,2个字节=int16,1个字节=byte</param>
        /// <returns></returns>
        private int GetBodyLengthFromHeader(byte[] header, int offset, int length, int lenStartIndex, int lenBytesCount)
        {
            var headerData = new byte[lenBytesCount];
            Array.Copy(header, offset + lenStartIndex, headerData, 0, lenBytesCount);//
            if (lenBytesCount == 1)
            {
                int i = headerData[0];
                return i;
            }
            else if (lenBytesCount == 2)
            {
                int i = BitConverter.ToInt16(headerData, 0);
                return i;
            }
            else //  if (lenBytesCount == 4)
            {
                int i = BitConverter.ToInt32(headerData, 0);
                return i;
            }
        }
    }
二、客户端
 public class MyTcpClient
    {
        private System.Net.Sockets.TcpClient tcpClient;
        public MyTcpClient(string ip, int port)
        {

            tcpClient = new System.Net.Sockets.TcpClient(ip, port);
            byte[] recData = new byte[1024];
            Action a = new Action(() =>
            {
                while (true)
                {
                    tcpClient.Client.Receive(recData);
                    var msg = System.Text.Encoding.UTF8.GetString(recData);
                    Console.WriteLine(msg);
                }
            });
            a.BeginInvoke(null, null);

        }

        public void Send(string message)
        {
            var data = System.Text.Encoding.UTF8.GetBytes(message);
            tcpClient.Client.Send(data);
        }
        public void Send(byte[] message)
        {
            tcpClient.Client.Send(message);
        }
    }
public class SuperSocketMessage
    {
        public byte[] Start;//4个字节
        public ushort Type;//2个字节, 1表示文字消息,2表示图片消息,其他表示未知,不能解析
        public int Len;//4个字节
        public string Message;//文本信息
        public byte[] Tail;//消息结尾

        public SuperSocketMessage()
        {
            Start = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF };
            Tail = new byte[] { 0x1F, 0x1F, 0x1F, 0x1F };
        }

        public byte[] ToBytes()
        {
            List<byte> list = new List<byte>();
            list.AddRange(Start);
            var t = BitConverter.GetBytes(Type);
            list.AddRange(t);

            var t3 = System.Text.Encoding.UTF8.GetBytes(Message);
            var t2 = BitConverter.GetBytes(t3.Length);//注意,这里不是Message.Length,而是Message转化成字节数组后的Lenght

            list.AddRange(t2);
            list.AddRange(t3);

            return list.ToArray();
        }
    }
        private void button1_Click(object sender, EventArgs e)
        {
            MyTcpClient c = new MyTcpClient("127.0.0.1", 2020);
            SuperSocketMessage msg = new SuperSocketMessage();
            msg.Type = 1;
            msg.Message = "aaa"; ;
            byte[] bytes = msg.ToBytes();
            string hexString = BitConverter.ToString(bytes).Replace("-", "");
            c.Send(msg.ToBytes());

        }
来源:https://blog.csdn.net/ba_wang_mao/article/details/118788365

 

标签:SuperSocket,appServer,C#,FixedHeaderReceiveFilter,int,new,byte,public,字节
From: https://www.cnblogs.com/ywtssydm/p/18510390

相关文章

  • Webpack搭建本地服务器
    为什么要搭建本地服务器webpack-dev-server认识模块热替换(HMR)开启HMR框架的HMR......
  • J. New Energy Vehicle
    怎样实现自定义排序函数的堆呢?从C++11开始,如果使用lambda函数自定义Compare则需要将其作为构造函数的参数代入,如:priority_queue<int,vector<int>,decltype(cmp)>q(cmp);decltype说明符可以推断表达式的类型当然本题其实不需要自定义排序函数,因为在调用排序运算符时,决......
  • 【SRC】记一次信息收集实战分享
    重点:1、Google搜索语法-搜索账号密码SFZ等2、week-passwd-爆破密码3、oneforall-爆破子域名4、windfire-检测存活URL5、社工原文首发在:先知社区https://xz.aliyun.com/t/15944选择目标进入补天,选择一个目标信息收集ip使用nslookupxxx.xxx.com只有一个ip回显,......
  • 2024最新最全【CUDA Toolkit 12.3】下载安装零基础教程【附安装包】_cuda12.3下载
    官网地址:这里CUDA是英伟达公司开发的一种并行计算平台和编程模型。它利用GPU的强大计算能力,加速各种数学和科学计算、数据分析、机器学习、计算机视觉等任务。CUDA包括CUDA编程语言、CUDA运行时库、NVIDIA显卡等组件。CUDA的编写方式分为两种:CUDAC/C++和CUDAFortran。开......
  • 网络安全中什么是CC攻击?CC攻击怎么防御?黑客技术零基础入门到精通,收藏这一篇就够了!
    前言这是晓晓给粉丝盆友们整理的网络安全渗透测试入门阶段dos与ddos渗透与防御基础教程喜欢的朋友们,记得给晓晓点赞支持和收藏一下,关注我,学习黑客技术。随着互联网的发展和技术的进步,网络安全问题日益严峻,网络攻击手段层出不穷,其中CC攻击就是一种比较常见的网络攻击手段......
  • 【揭秘】Logback日志如何实现请求唯一追踪ID,提升系统监控效能!
    在分布式系统中,为了方便追踪和调试问题,通常会为每个请求生成一个唯一的追踪ID(TraceID)。这个ID可以在整个请求的生命周期中传递,并在日志中记录。Logback是一个流行的Java日志框架,可以通过自定义MDC(MappedDiagnosticContext)来实现这一功能。以下是如何在Logback中添......
  • 【揭秘】如何用ConstraintValidator自定义校验注解,让你的代码更简洁高效!
    在Java中,自定义校验注解(CustomValidationAnnotation)通常用于BeanValidation框架(如HibernateValidator),以便对特定字段或方法参数进行验证。以下是如何创建和使用自定义校验注解的详细步骤和代码示例:1.定义自定义校验注解首先,我们需要定义一个自定义校验注解。这个注解需......
  • C语言和Rust在安全性特性上的区别
    #C语言和Rust在安全性特性上的区别在探讨C语言和Rust在安全性特性上的区别时,我们可以明确地指出几个核心观点:Rust提供了内存安全保证、并发安全、以及错误处理机制,这些特性在编译时就能够避免许多常见的错误类型,显著提高了软件的安全性和可靠性。其中,内存安全保证是Rust最为突......
  • 【NSSCTF】nssctf2024秋季招新赛赛
    【NSSCTF】2024年NSSCTF秋季招新赛Reverse签到?key加密密文:主加密程序解密脚本:a=[32,39,38,37,44,45,15,34,20,30,33,24,9,223,200,28,231,5,229,226,238,26,230,4,217,201,227,10,......
  • 深入理解openstack neutron
    1.neutronnetwork数据结构说明网络分为租户网络和运营商网络,租户网络由租户创建,运营商网络由管理员创建网络结构里没有网络类型和vlanid,vni这些信息的字段,是由配置文件决定的#[etc/neutron/plugins/ml2/ml2_conf.ini]tenant_network_types=vxlan[ml2_type_vxlan]v......