.Net网络通信组件 - TouchSocket

news2024/9/22 1:11:19

文章目录

  • .Net网络通信组件 - TouchSocket
    • 1、新建.Net8控制台项目
    • 2、Nuget安装TouchSocket组件
    • 3、编写服务端代码
    • 4、编写客户端代码
    • 5、编写Program代码
    • 6、运行效果
    • 7、日志组件(NLog)参考我的另一篇博客

.Net网络通信组件 - TouchSocket

1、新建.Net8控制台项目

2、Nuget安装TouchSocket组件

install-package TouchSocket

3、编写服务端代码


using System.Text;
using TestTouchSocketApp.TouchSockets.Dtos;
using TouchSocket.Core;
using TouchSocket.Sockets;

namespace TestTouchSocketApp.TouchSockets
{
    public class TestTouchSocketServer
    {
        public TestTouchSocketServer()
        {
            //初始化服务端
            InitServer();
        }

        public TcpService TcpService { get; set; }
        public List<TouchSocketClientDto> Clients { get; set; }

        /// <summary>
        /// 初始化服务端
        /// </summary>
        private void InitServer()
        {
            //初始化
            TcpService = new TcpService();
            //初始化
            Clients = new();
            TcpService.Connecting += (client, e) =>
            {
                //返回
                return EasyTask.CompletedTask;
            };
            TcpService.Connected += (client, e) =>
            {
                //初始化
                TouchSocketClientDto clientDto = new();
                //赋值
                clientDto.Index = Clients.Count + 1;
                clientDto.ClientId = client.Id;
                clientDto.Host = client.IP;
                clientDto.Port = client.Port;
                clientDto.Online = true;
                clientDto.ConnectTime = DateTime.Now;
                //添加
                Clients.Add(clientDto);
                //记录日志
                LingbugLogUtil.Info($"有新客户端上线啦:{TouchSocketClientDto.GetContentStr(clientDto)}");
                //返回
                return EasyTask.CompletedTask;
            };
            TcpService.Received += (client, e) =>
            {
                try
                {
                    //读取
                    var bytes = e.ByteBlock.ToArray();
                    //读取
                    var clientMsg = Encoding.UTF8.GetString(bytes);
                    //log
                    string log = $"Server Received,收到客户端发送的消息:【{clientMsg}】";
                    //记录日志
                    LingbugLogUtil.Info(log);
                }
                catch (Exception exception)
                {
                    //记录日志
                    LingbugLogUtil.Error($"Server Received,读取客户端消息异常:{exception.Message}", exception);
                }
                //返回
                return EasyTask.CompletedTask;
            };
            TcpService.Closing += (client, e) =>
            {
                //返回
                return EasyTask.CompletedTask;
            };
            TcpService.Closed += (client, e) =>
            {
                foreach (var clientDto in Clients.FindAll(r => r.ClientId == client.Id))
                {
                    //赋值
                    clientDto.Online = false;
                    clientDto.DisConnectTime = DateTime.Now;
                    //记录日志
                    LingbugLogUtil.Info($"客户端已下线:{TouchSocketClientDto.GetContentStr(clientDto)}");
                }
                //返回
                return EasyTask.CompletedTask;
            };
            //初始化
            var config = new TouchSocketConfig();
            //赋值
            config.SetListenIPHosts(new IPHost[] { "127.0.0.1:9990", "127.0.0.1:9991" });
            config.SetMaxCount(100);
            config.SetThreadCount(10);
            //配置
            TcpService.Setup(config);
            //启动
            TcpService.Start();
            //打印
            LingbugLogUtil.Info("server is started,listening on 127.0.0.1:9990,127.0.0.1:9991");
        }

        /// <summary>
        /// 获取在线客户端
        /// </summary>
        /// <returns></returns>
        public List<TouchSocketClientDto> GetConnectedClients()
        {
            //数据
            var clients = Clients ?? new();
            //过滤
            return clients.FindAll(r => r.Online);
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="clientId"></param>
        /// <param name="msg"></param>
        public void SendMsg(string clientId, string msg)
        {
            //发送消息
            TcpService.Send(clientId, msg);
        }
    }
}

4、编写客户端代码


using System.Text;
using TouchSocket.Core;
using TouchSocket.Sockets;

namespace TestTouchSocketApp.TouchSockets
{
    public class TestTouchSocketClient
    {
        public TestTouchSocketClient(string listenServer)
        {
            //初始化客户端
            InitClient(listenServer);
        }

        public TcpClient TcpClient { get; set; }

        /// <summary>
        /// 初始化客户端
        /// </summary>
        /// <param name="listenServer"></param>
        private void InitClient(string listenServer)
        {
            //初始化
            TcpClient = new TcpClient();
            TcpClient.Connecting += (client, e) =>
            {
                //返回
                return EasyTask.CompletedTask;
            };
            TcpClient.Connected += (client, e) =>
            {
                //返回
                return EasyTask.CompletedTask;
            };
            TcpClient.Received += (client, e) =>
            {
                try
                {
                    //读取
                    var bytes = e.ByteBlock.ToArray();
                    //读取
                    var serverMsg = Encoding.UTF8.GetString(bytes);
                    //log
                    string log = $"Client Received,收到服务器发送的消息:【{serverMsg}】";
                    //记录日志
                    LingbugLogUtil.Info(log);
                }
                catch (Exception exception)
                {
                    //记录日志
                    LingbugLogUtil.Error($"Client Received,读取服务器消息异常:{exception.Message}", exception);
                }
                //返回
                return EasyTask.CompletedTask;
            };
            TcpClient.Closing += (client, e) =>
            {
                //返回
                return EasyTask.CompletedTask;
            };
            TcpClient.Closed += (client, e) =>
            {
                //返回
                return EasyTask.CompletedTask;
            };
            //初始化
            var config = new TouchSocketConfig();
            //赋值
            config.SetRemoteIPHost(new IPHost(listenServer));
            //配置
            TcpClient.Setup(config);
            //启动
            TcpClient.Connect();
            //打印
            LingbugLogUtil.Info($"client is connected to server,server is {listenServer}");
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="msg"></param>
        public void SendMsg(string msg)
        {
            //发送消息
            TcpClient.Send(msg);
        }
    }
}

5、编写Program代码


using TestTouchSocketApp.TouchSockets;
using TestTouchSocketApp.TouchSockets.Dtos;

namespace TestTouchSocketApp
{
    internal class Program
    {
        static void Main(string[] args)
        {
            try
            {
                //打印
                Console.WriteLine("请输入,1:服务端;2:客户端;");
                //读取
                var input = Console.ReadLine();
                if (input == "1")
                {
                    //初始化
                    TestTouchSocketServer server = new();
                    //打印
                    Console.WriteLine("请输入要发送给客户端的消息:");
                    //读取
                    var msg = Console.ReadLine();
                    //打印
                    Console.WriteLine("要发送给哪个客户端,当前连接的客户端有:");
                    //获取在线客户端
                    var clients = server.GetConnectedClients();
                    foreach (var client in clients)
                    {
                        //打印
                        Console.WriteLine(TouchSocketClientDto.GetContentStr(client));
                    }
                    //读取
                    var clientId = Console.ReadLine();
                    //发送消息
                    server.SendMsg(clientId, msg);
                }
                else if (input == "2")
                {
                    //打印
                    Console.WriteLine("请输入要连接的服务端地址:");
                    //读取
                    var server = Console.ReadLine();
                    //初始化
                    TestTouchSocketClient client = new(server);
                    //打印
                    Console.WriteLine("请输入要发送给服务器的消息:");
                    //读取
                    var msg = Console.ReadLine();
                    //发送消息
                    client.SendMsg(msg);
                }
            }
            catch (Exception e)
            {
                //记录日志
                LingbugLogUtil.Error($"程序异常:{e.Message}", e);
            }
            //读取
            Console.ReadKey();
        }
    }
}

6、运行效果

在这里插入图片描述

7、日志组件(NLog)参考我的另一篇博客

.Net日志组件之NLog的使用和配置

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2146704.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络安全学习路线,史上最全网络安全学习路线整理

很多小伙伴在网上搜索网络安全时&#xff0c;会出来网络安全工程师这样一个职位&#xff0c;它的范围很广&#xff0c;只要是与网络安全挂钩的技术人员都算网络安全工程师&#xff0c;一些小伙伴就有疑问了&#xff0c;网络安全现在真的很火吗&#xff1f; 那么无涯就带大家看…

《高等代数》范德蒙德行列式(应用)

说明&#xff1a;此文章用于本人复习巩固&#xff0c;如果也能帮助到大家那就更加有意义了。 注&#xff1a;1&#xff09;此题中的行列式是缺失了一行的范德蒙德行列式&#xff0c;解题思路是将其与范德蒙德行列式进行对比&#xff0c;我们将其添上一行和一列补成范德蒙德行列…

解决SPI1在发送和接收8位数据时出现接收不同步的问题

STM32G474的SPI1工作在主机模式&#xff0c;将SPI1_MISO和SPI1_MOSI连接一起&#xff0c;实现自发自收测试。但是在“使用8位数据自发自收时”时&#xff0c;发现接收数据不是同步的。虽然SPI1初始化正确&#xff0c;但是还需要对SPI1_DR寄存器进行强制转换&#xff0c;否则&am…

2024年网络安全人才发展报告一览

前不久&#xff0c;由信通院、工业和信息化部教育与考试中心、中国网络空间新兴技术安全创新论坛等单位联合发布了《2024网络安全产业人才发展报告》&#xff0c;长达87页的调研报告深度剖析了目前中国网络安全产业人才供需、分布、就业等现状&#xff0c;这里&#xff0c;星尘…

C++ 第三讲:内存管理

C 第三讲&#xff1a;内存管理 1.C内存分布2.内存管理方式2.1C语言内存管理方式2.2C内存管理方式2.2.1new\delete操作内置类型2.2.2new\delete操作自定义类型 3.operator new与operator delete函数4.new和delete实现原理4.1内置类型4.2自定义类型 5.定位new5.1内存池的基本了解…

基于Java的学生档案管理系统的设计与实现

基于springbootvue实现的学生档案管理系统 &#xff08;源码L文ppt&#xff09;4-065 第4章 系统设计 4.1 总体功能设计 学生档案管理系统的总体功能设计包括学生信息管理、课程管理、教师信息管理、成绩管理和系统配置管理。系统将提供用户友好的界面&#xff0c;支…

【网络】传输层协议TCP

TCP协议 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议&#xff0c;由IETF的RFC 793定义。TCP在IP&#xff08;Internet Protocol&#xff0c;互联网协议&#xff09;网络层上提供…

【Linux】—— muduo网络库的安装配置与使用

muduo网络库编程 Linux环境下Epollpthread线程库 Boost库安装与使用 安装Boost库 下载boost库源码&#xff0c;linux环境解压 tar -zxvf boost_1_69_0.tar.gz 解压完成后&#xff0c;进入该目录&#xff0c;查看内容 运行bootstrap.sh工程编译构建程序 ./bootstrap.sh …

javascript-代码执行原理

js 是解释型语言 js 引擎执行流程 分为两个阶段: 语法分析执行阶段执行阶段涉及的数据结构: 调用栈。处理执行上下文和执行代码内存堆。给对象分配内存任务队列。暂存待执行的任务,分为宏任务队列和微任务队列语法分析 词法分析 > 语法分析 > 代码生成(字节码) …

封装svg图片

前言 项目中有大量svg图片&#xff0c;为了方便引入&#xff0c;所以对svg进行了处理 一、svg是什么&#xff1f; svg是可缩放矢量图形&#xff0c;是一种图片格式 二、使用步骤 1.创建icons文件夹 将icons文件夹放进src中&#xff0c;并创建一个svg文件夹和index.js&…

深入探索迭代器模式的原理与应用

&#x1f3af; 设计模式专栏&#xff0c;持续更新中 欢迎订阅&#xff1a;JAVA实现设计模式 &#x1f6e0;️ 希望小伙伴们一键三连&#xff0c;有问题私信都会回复&#xff0c;或者在评论区直接发言 迭代器模式 &#x1f4bb; 迭代器模式 (Iterator Pattern) 是一种行为设计模…

【LeetCode】每日一题 2024_9_19 最长的字母序连续子字符串的长度(字符串,双指针)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动&#xff01; 题目&#xff1a;坐上公交的最晚时间 代码与解题思路 func longestContinuousSubstring(s string) (ans int) { // 题目要求&#xff1a; 最长 的 字母序连续子字符串 的长度// 双指针&#xff0c;start …

【学习笔记】线段树分裂

前言 有线段树合并就应该有线段树分裂。它是线段树合并的逆过程。具体的&#xff0c;你需要以权值线段树中第 k 小的数为分界线&#xff0c;把线段树分成两半。 算法流程 和线段树上二分类似。假设原来的线段树为 u&#xff0c;要分裂出线段树 v 记左子树的权值为 val。如果…

CodeMeter助力软件授权与IP保护,保障工业自动化与物联网安全

随着工业自动化的飞速发展&#xff0c;Hilscher的开放工业4.0联盟&#xff08;OI4&#xff09;旗舰店应运而生&#xff0c;将应用商店模式引入工业领域。凭借CodeMeter授权和加密技术的支持&#xff0c;该商店为工业用户提供了一个安全且开放的应用程序和解决方案平台。该平台不…

超声波清洗机哪个品牌好用又实惠?精选业内四款优质清洗机推荐

超声波清洗机作为一种创新的清洁解决方案&#xff0c;凭借其深入微观的清洁效能、简便的操作方式以及对物品的细腻呵护&#xff0c;正逐渐成为广受喜爱的清洁良品。不过&#xff0c;市面上品牌林立、型号多样&#xff0c;价格亦波动不一&#xff0c;这无疑为消费者选购时平添了…

ATT&CK靶机实战系列之vulnstack2

声明: 本文章只是用于网络安全交流与学习&#xff0c;若学者用学到的东西做一些与网络安全不相关的事情&#xff0c;结果均与本人无关&#xff01;&#xff01;&#xff01; 靶场环境: 使用kali作为hacker的攻击机器&#xff0c;来对web pc dc进行攻击。 这里声明一下: 关于…

Cesium billboard 自定义shader实现描边效果

Cesium billboard 自定义shader实现描边效果 uniform sampler2D u_atlas;uniform vec2 dimensions;in vec2 v_textureCoordinates;in vec4 v_pickColor;in vec4 v_color;in float v_splitDirection;void main(){if (v_splitDirection < 0.0 && gl_FragCoord.x > …

一文详解可视化大屏技术在地震监测中的作用!

昨天&#xff0c;安徽合肥市肥东县发生地震&#xff0c;震级达到4.7级&#xff0c;震源深度12千米。这一事件再次提醒我们&#xff0c;地震的威胁无处不在&#xff0c;及时有效的地震预警对于减少灾害损失至关重要。四川省作为地震活动频繁的地区&#xff0c;近年来在地震监测和…

配置环境-keil

配置keil -- 先将keil安装配置好&#xff0c;包括库 一、STM32 -- STM32是意法半导体&#xff08;意大利&#xff09;采用ARM公司设计的内核&#xff0c;设计一系列32位单片机芯片。 1、STM32开发的几种方式 2、STM32寄存器和库函数版本的工程创建 新建文件夹 复制相关文件…

【机器学习(八)】分类和回归任务-因子分解机(Factorization Machines,FM)-Sentosa_DSML社区版

文章目录 一、算法概念二、算法原理&#xff08;一&#xff09; FM表达式&#xff08;二&#xff09;时间复杂度&#xff08;三&#xff09;回归和分类 三、算法优缺点&#xff08;一&#xff09;优点&#xff08;二&#xff09;缺点 四、FM分类任务实现对比&#xff08;一&…