P2P服务端模型配合 Tool.net P2pServerAsync 类使用

Tool.Net 支持的 P2P 服务器模型实例

  • 说明
    • 服务器部分相关代码
    • 相关调用实例
      • Tcp版本
      • Udp版本
    • 最后附一张思维图

说明

  • 当前文章,仅是Tool.Net 开源库的一个缩影。
  • 本次更新V5.0版本以上提供支持。
  • 可以提供简单实现P2P功能用于业务开发。

服务器部分相关代码

完整代码(适用于自定义的场景).

using Tool.Sockets.Kernels;
using Tool.Sockets.P2PHelpr;
using Tool.Sockets.TcpHelper;
using Tool.Sockets.UdpHelper;

await Console.Out.WriteLineAsync("P2P服务器·支持“TCP” OR “UDP”");

static async ValueTask Completed(UserKey a1, EnServer b1, DateTime c1, string name)
{
    await Console.Out.WriteLineAsync($"[{name}]IP:{a1} \t{b1} \t{c1:yyyy/MM/dd HH:mm:ss:fffffff}");
}

EnumEventQueue.OnInterceptor(EnServer.SendMsg, false);
EnumEventQueue.OnInterceptor(EnServer.Receive, false);
EnumEventQueue.OnInterceptor(EnServer.HeartBeat, false);

TcpServerAsync tcpServerAsync = new(NetBufferSize.Size8K, true);
UdpServerAsync udpClientAsync = new(NetBufferSize.Size8K, true);

string ip = "0.0.0.0";
int port = 11111;

tcpServerAsync.SetCompleted((a1, b1, c1) => Completed(a1, b1, c1, "TCP"));
udpClientAsync.SetCompleted((a1, b1, c1) => Completed(a1, b1, c1, "UDP"));

tcpServerAsync.SetReceived(async (receive) =>
{
    using (receive)
    {
        if (P2pServerAsync.IsP2pAuth(receive.Span, out var ipnum))
        {
            string ok = $"[TCP]{ipnum}->{receive.Key} \t{DateTime.Now:yyyy/MM/dd HH:mm:ss:fffffff}";
            using var sendBytes = tcpServerAsync.CreateSendBytes(receive.Client, 16);
            sendBytes.SetMemory(P2pServerAsync.TcpTop);
            sendBytes.SetMemory(ipnum.Span, 4);
            sendBytes.SetMemory(receive.Key.Span, 10);
            await tcpServerAsync.SendAsync(sendBytes);
            await Console.Out.WriteLineAsync(ok);
        }
    }
});

udpClientAsync.SetReceived(async (receive) =>
{
    using (receive)
    {
        if (P2pServerAsync.IsP2pAuth(receive.Span, out var ipnum))
        {
            string ok = $"[UDP]{ipnum}->{receive.Key} \t{DateTime.Now:yyyy/MM/dd HH:mm:ss:fffffff}";
            using var sendBytes = udpClientAsync.CreateSendBytes(receive.Client, 16);
            sendBytes.SetMemory(P2pServerAsync.UdpTop);
            sendBytes.SetMemory(ipnum.Span, 4);
            sendBytes.SetMemory(receive.Key.Span, 10);
            await udpClientAsync.SendAsync(sendBytes);
            await Console.Out.WriteLineAsync(ok);
        }
    }
});

await tcpServerAsync.StartAsync(ip, port);
await udpClientAsync.StartAsync(ip, port);

while (Console.ReadKey(true).Key != ConsoleKey.Escape) ;

相关调用实例

Tcp版本

P2pServerAsync p2PServerAsync0 = await P2pServerAsync.GetFreeTcp();
P2pServerAsync p2PServerAsync1 = await P2pServerAsync.GetFreeTcp();

TcpClientAsync p2PClientAsync0 = new(NetBufferSize.Default, true);
var task0 = p2PClientAsync0.P2PConnectAsync(p2PServerAsync0.LocalEP, p2PServerAsync1.RemoteEP);

TcpClientAsync p2PClientAsync1 = new(NetBufferSize.Default, true);
var task1 = p2PClientAsync1.P2PConnectAsync(p2PServerAsync1.LocalEP, p2PServerAsync0.RemoteEP);

Task.WaitAll(task0, task1);

Udp版本

P2pServerAsync p2PServerAsync0 = await P2pServerAsync.GetFreeUdp();
P2pServerAsync p2PServerAsync1 = await P2pServerAsync.GetFreeUdp();

UdpClientAsync p2PClientAsync0 = new(NetBufferSize.Default, true);
var task0 = p2PClientAsync0.P2PConnectAsync(p2PServerAsync0.LocalEP, p2PServerAsync1.RemoteEP);

UdpClientAsync p2PClientAsync1 = new(NetBufferSize.Default, true);
var task1 = p2PClientAsync1.P2PConnectAsync(p2PServerAsync1.LocalEP, p2PServerAsync0.RemoteEP);

Task.WaitAll(task0, task1);

最后附一张思维图

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringCloud微服务03-微服务保护-分布式事务-MQ基础-MQ高级

一、微服务保护 1.雪崩问题 如何做好后备方案就是后续: 2.雪崩解决方案 某一个服务的线程是固定的,出现故障线程占满后,就不会让取调用这个服务,对其他服务就没有影响。 3.Sentinel ①初识Sentinel 配置过程:day05-服…

核心四:线程的一生

4、核心四:线程的一生💟 4.1 New 已创建但还未启动的新线程。 我们new Thread之后,线程已经实现了一些准备工作。但没有运行run方法,因为没有使用start来开启线程。此时,线程处于New状态。 4.2 Runnable&#xff08…

element-ui的Form 表单有些项的参数校验

项目场景: 提示:项目相关背景: 项目场景:有时候自己的Form 表单中的某几项引入的一些项不好去校验 这样的咋去校验呢? 解决方案: 提示:问题的具体解决方案: 例如:写一…

将Surface的分辨率减半以省电(二合一本\笔记本电脑适用)

【完全自定义分辨率教程】这篇教程用于将Surface之类的高分屏(高分辨率)的二合一本或笔记本等的分辨率调整为原来的一半,以实现省电等目的。 下载CRU(Custom Resolution Utility)解压后,打开CRU.exe选择当…

【每日刷题】Day48

【每日刷题】Day48 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 872. 叶子相似的树 - 力扣(LeetCode) 2. 114. 二叉树展开为链表 - 力扣&…

每日一题《leetcode--382.链表随机结点》

https://leetcode.cn/problems/linked-list-random-node/ 这道题我们首先看到题目中的要求:在单链表中随机选取一个链表中的结点,要使每个结点被选取的概率是一样的。 当我们看到随机这两个字时,应该就会想起rand()这个函数。接着我们把使用这…

Rhinoceros v7.5 解锁版安装教程 (3D三维造型软件)

前言 Rhinoceros 中文名称犀牛是一款超强的三维建模工具,全称Rhinoceros,Rhino是美国Robert McNeel & Assoc开发的PC上强大的专业3D造型软件,它可以广泛地应用于三维动画制作、工业制造、科学研究以及机械设计等领域。它能轻易整合3DS M…

SpringFramework实战指南

二、SpringFramework实战指南 目录 一、技术体系结构 1.1 总体技术体系1.2 框架概念和理解 二、SpringFramework介绍 2.1 Spring 和 SpringFramework概念2.2 SpringFramework主要功能模块2.3 SpringFramework 主要优势 三、Spring IoC容器和核心概念 3.1 组件和组件管理概念3…

element-ui手机区号+手机号

需求场景 项目开发中对方要求手机号带上全球区号 需求分析 项目使用的是若依前端框架,element-ui的框架。尝试使用已经网上的组件vue-country-intl等发现不怎么适配element-ui的样式等。这还不是关键的,关键的是弹窗中使用这些组件发现区号的下拉展示框…

面试框架【面试准备】

前言 2023-9-12 12:12:04 2023-09-14 16:13:04 公开发布于 2024-5-22 00:16:21 以下内容源自《【面试准备】》 仅供学习交流使用 版权 禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作者是CSDN日星月云 博客主页是https://blog.csdn.net/qq_51625007 禁止其他平…

文件流下载优化:由表单提交方式修改为Ajax请求

如果想直接看怎么写的可以跳转到 解决方法 节! 需求描述 目前我们系统导出文件时,都是通过表单提交后,接收文件流自动下载。但由于在表单提交时没有相关调用前和调用后的回调函数,所以我们存在的问题,假如导出数据需…

idea上传git命令

git init git remote add origin git add . git commit -m "标题" git push -u origin master

《Fundamentals of Power Electronics》——开关电源环路稳定性分析(中)

7.传递函数 传递函数,简单的理解就是输入和输出之间的关系。通过传递函数可以知道这个系统对不同频率信号响应,而这些响应通过画出传递函数的波特图又能知道传递函数在某点频率的相位和增益。一个系统要稳定可靠,那就需要一定的相位裕度和增…

基础3 探索JAVA图形编程桌面:逻辑图形组件实现

在一个宽敞明亮的培训教室里,阳光透过窗户柔和地洒在地上,教室里摆放着整齐的桌椅。卧龙站在讲台上,面带微笑,手里拿着激光笔,他的眼神中充满了热情和期待。他的声音清晰而洪亮,传遍了整个教室:…

【嵌入式芯片开发】不使用MicroLib的串口重定向万能预编译配置(适用于ARMCC、AC6等不同的编译器及版本)

【嵌入式芯片开发】不使用MicroLib的串口重定向万能预编译配置(适用于ARMCC、AC6等不同的编译器及版本) 文章目录 基本的串口重定向接收中断与scanf不能同时工作重定向卡死、低功耗一直唤醒 串口重定向万能预编译配置附录:Cortex-M架构的Sys…

2024042102-array-list

数组 Array 一、前言 数组是数据结构还是数据类型? 数组只是个名称,它可以描述一组操作,也可以命名这组操作。数组的数据操作,是通过 idx->val 的方式来处理。它不是具体要求内存上要存储着连续的数据才叫数据,而…

Qt moc系统的黑魔法?

Qt的元对象系统(Meta-Object System)是Qt框架的核心功能之一,为C语言增加了一些动态特性,借助元对象系统Qt可以实现以下功能 信号与槽机制(Signals and Slots)运行时类型信息(Run-Time Type In…

倍思科技获14项红点设计奖,引领中国移动数码品牌创新风潮

近日,国际红点设计大奖公布了2024年获奖名单,中国移动数码品牌倍思科技凭借其出色的产品设计实力,一举斩获14项红点设计奖。这些获奖产品涵盖了充电、音频、车用等多个品类,展现了倍思科技在创新设计和实用功能方面的卓越成就。 红点设计奖作为世界知名设计竞赛,素有“设计界的…

【论文笔记】| 微调LLM晶体生成

【论文笔记】| 微调LLM晶体生成 Fine-Tuned Language Models Generate Stable Inorganic Materials as Text NYU, ICLR 2024 Theme:Material Generation Main work: 微调大型语言模型以生成稳定的材料 可靠性:在样本结构中,90% …

【因果推断从入门到精通二】随机实验3

目录 检验无因果效应假说 硬币投掷的特殊性何在? 检验无因果效应假说 无因果效应假说认为,有些人存活,有些人死亡,但接受mAb114治疗而不是ZMapp与此无关。在174例接受mAb14治疗的患者中,113/17464.9%存活了28天&…