工業數采引擎-通信鏈路SOCKET

通信庫:DotNetty

封裝實現:TcpServer、TcpClient、Udp

TCP協議特性:面向連接協議;每個新連接都會創建獨立的ChannelHandler實例;TcpHandler構造函數在每次客戶端連接時觸發
UDP協議特性:無連接協議;整個服務端只創建單例UdpHandler;所有UDP數據包共享同一個處理器實例;UdpHandler構造函數僅在服務啟動時觸發一次

Server
1. 端口復用
2. 定時清理鏈路

TcpClient
1. 指定本地ip及端口
2. 自動重連

其他
1. 上線,離線,數據接收消息通知
2. 接收緩沖數據存儲

復制代碼

using DotNetty.Buffers;
using FusionDrive.DotNetty.Util;
using FusionDrive.DotNetty.Util.decode;
using FusionDrive.DotNetty.Util.socket;
using System.Net;
using System.Text;namespace FusionDrive.DotNetty
{internal class Program{static void Main(string[] args){//Test_Server();Test_Client();Console.ReadLine();}static void Test_Server(){OHMDecode ohm = new OHMDecode();PipeManager.CheckLink();var server = new CommunicationServer();//server.Listen(8801);server.Listen(8801, isTcp: true, isUdp: true, udpTargetEndPoint: new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8802));server.OnPipeOnline += async (session) =>{Logger.Info($"-> {session.RemoteAddress?.ToString()} 上線"); };server.OnPipeOffline += async (session) =>{Logger.Info($"<- {session.RemoteAddress?.ToString()} 離線");};server.OnPipeReceived += async (session, buffer) =>{// dtu模式if (session.IsFirstConnect){// 心跳包session.IsFirstConnect = false;var sessionId = Encoding.UTF8.GetString(buffer);session.UpdateSessionId(sessionId);// 下發TCP指令SendData(session.SessionId);// 清理PipeManager.ClearByteBuffer(sessionId);}else{ohm.ProtocolFormat(session.SessionId, session.ByteBuffer);}// 下發UDP指令SendData(session.SessionId, session.TargetEndPoint);SendData(session.SessionId, session.RemoteAddress);};}static void Test_Client(){AirDecode air = new AirDecode();var tcpClient = new TcpClient();tcpClient.Connect("127.0.0.1", 8801, autoConect:true);tcpClient.OnPipeOnline += async (session) =>{Logger.Info($"-> {session.RemoteAddress?.ToString()} 上線");};tcpClient.OnPipeOffline += async (session) =>{Logger.Info($"<- {session.RemoteAddress?.ToString()} 離線");};tcpClient.OnPipeReceived += async (session, buffer) =>{air.ProtocolFormat(session.SessionId, session.ByteBuffer);////tcpClient.DisConnect();};}static void SendData(string sessionId, EndPoint endPoint = null){IByteBuffer message = Unpooled.Buffer();message.WriteString("*TRG\r\n", Encoding.UTF8);var p = PipeManager.CheckSession(sessionId, out string errmsg);p.Send(message, endPoint);} }
}

復制代碼

復制代碼

using DotNetty.Buffers;
using System.Text;namespace FusionDrive.DotNetty.Util.decode
{public class AirDecode : NettyDecode{const byte HEAD = 02;public override void ProtocolFormat(string sessionId, IByteBuffer oldBuffer){ try{if (IsHeadLost(oldBuffer, 1)) return ;// 掉包bool headok = false;// 垃圾包處理oldBuffer.MarkReaderIndex();while (oldBuffer.IsReadable()){byte head1 = oldBuffer.ReadByte();// 1字節:標識頭if (HEAD == head1){headok = true;break;}else{oldBuffer.MarkReaderIndex();}}if (!oldBuffer.IsReadable()){if (!headok) return ; // 垃圾包}// 3字節:ascii長度if (IsBagLost(oldBuffer, 3)) return ;// 掉包byte[] arrlen = new byte[3]; oldBuffer.ReadBytes(arrlen);int len = Convert.ToInt32(Encoding.ASCII.GetString(arrlen));// n字節:數據包len = len + 2;// 包含結束幀及校驗位if (IsBagLost(oldBuffer, len)) return ;// 掉包byte[] data = new byte[len]; oldBuffer.ReadBytes(data);Logger.Info($"AirDecode sessionId:{sessionId},data:{Common.ToHexString(data, data.Length, true)}");// 壓力值string pressureValue = "999";var pressureFlg = Encoding.ASCII.GetString(new byte[] { data[55] });var pressureNumber = Encoding.ASCII.GetString(new byte[] {data[56], data[57], data[58], data[59], data[60],data[61], data[62], data[63], data[64], data[65] });// 可能為----------- if (double.TryParse(pressureNumber, out double result1)){pressureNumber = result1.ToString();pressureValue = pressureFlg + pressureNumber;}Logger.Info($"AirDecode 壓力值:{pressureValue}");if (oldBuffer.IsReadable()){ProtocolFormat(sessionId, oldBuffer);// 處理粘包}else{oldBuffer.Clear();// 包完整,清理} }catch (Exception ex){Logger.Error($"AirDecode 協議解析錯誤,sessionId:{sessionId}:{ex.Message}");} }}
}

復制代碼

image

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/92350.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/92350.shtml
英文地址,請注明出處:http://en.pswp.cn/web/92350.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PHP小白零基礎入門(附視頻教程)

概述 PHP是一種通用開源腳本語言&#xff0c;常用于服務器端Web開發&#xff0c;具有語法簡單、上手快等特點。視頻教程&#xff1a;https://pan.quark.cn/s/8f214c23301b 搭建開發環境&#xff1a; 選擇集成工具&#xff1a;可選擇XAMPP&#xff08;支持Windows/Mac/Linux…

驗證碼等待時間技術在酒店自助入住、美容自助與社區場景中的應用必要性研究—仙盟創夢IDE

代碼 代碼 完整<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>驗證碼倒計時</title><s…

Flask從入門到實戰:基礎、進階、項目架構與接口測試

本文將帶你從零開始掌握Flask框架&#xff0c;涵蓋基礎使用、進階技巧、項目架構設計&#xff0c;并提供完整的接口測試客戶端代碼。 目錄一、Flask基礎入門1.1 Flask簡介與安裝1.2 第一個Flask應用1.3 路由與請求處理1.4 請求與響應處理二、Flask進階使用2.1 模板引擎Jinja22.…

華為云產品圖解

框架圖核心說明: 1. 分層邏輯清晰 基礎設施層(IaaS):提供最基礎的計算(ECS/BMS)、存儲(OBS/EVS)、網絡(VPC/CDN)資源,是所有上層服務的 “物理底座”。 平臺服務層(PaaS):基于 IaaS 構建,提供容器編排(CCE)、數據庫(GaussDB)、大數據與 AI(ModelArts)、中…

Git 中如何回退到以前的提交記錄?

回答重點要在 Git 中回退到以前的提交記錄&#xff0c;你可以使用 git reset 命令。這個命令有三個常用選項來控制你想要回退的程度&#xff1a;1&#xff09; git reset --soft <commit> &#xff1a;僅修改 HEAD 指針&#xff0c;不修改索引和工作區內容。2&#xff09…

JavaWeb03——基礎標簽及樣式(表單)(黑馬視頻筆記)

1.表單標簽 及 表單屬性表單標簽是 &#xff1a;<form> 表單屬性有&#xff1a;action 和 method&#xff1b;action屬性&#xff1a;規定向何處發送表單數據。method屬性&#xff1a;規定用什么方法發送數據。&#xff08;get和post&#xff09;get:在發送的url后面拼接…

STM32的SPI通信(軟件讀寫W25Q64)

在了解完I2C通信后&#xff0c;不免會接觸到到SPI通信。而一開始&#xff0c;可能會覺得兩者好似沒什么區別。為什么要學SPI呢&#xff0c;I2C和SPI有什么區別呢。為此我詳細展開說說。1.什么是 SPI&#xff1f;SPI&#xff0c;全稱 Serial Peripheral Interface&#xff0c;中…

子詞分詞器(Byte Pair Encoding + WordPiece)

參考文章&#xff1a;子詞分詞器BPE和WordPiece理解_wordpeice-CSDN博客 子詞分詞器BPE和WordPiece理解_wordpeice-CSDN博客 WordPiece 和 BPE 的區別-CSDN博客 點互信息&#xff08;PMI&#xff09;和正點互信息&#xff08;PPMI&#xff09;-CSDN博客 https://zhuanlan.z…

阿里招AI產品運營

AI產品運營&#xff08;崗位信息已經過jobleap.cn授權&#xff0c;可在csdn發布&#xff09;靈犀互娛 廣州收錄時間&#xff1a; 2025年08月05日職位描述負責AI技術在游戲行業的應用與落地&#xff0c;專注于海外市場的運營中臺建設&#xff1b; 將結合AI技術與游戲行業特點&a…

Git 分支遷移完整指南(結合分支圖分析)

基于分支圖的當前狀態分析 分支圖關鍵信息解讀?分支結構?&#xff1a; #mermaid-svg-gc9SPnwlbrM2FzHf {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-gc9SPnwlbrM2FzHf .error-icon{fill:#552222;}#mermaid-svg-…

小程序省市級聯組件使用

背景。uni-data-picker組件用起來不方便。調整后級聯效果欠佳&#xff0c;會關閉彈窗需要重新選擇。解決方案。讓cursor使用uniapp 原生組件生成懶加載省市級聯 <template><view class"picker-cascader"><view class"cascader-label">&l…

Java技術棧/面試題合集(8)-Redis篇

場景 Java入門、進階、強化、擴展、知識體系完善等知識點學習、性能優化、源碼分析專欄分享: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/140870227 通過對面試題進行系統的復習可以對Java體系的知識點進行查漏補缺。 注: 博客: 霸道流氓氣質-CSDN博…

川翔云電腦:引領開啟算力無邊界時代

一、何為云電腦&#xff1f;重新定義“主機”概念 云電腦將傳統本地計算機的核心硬件資源&#xff08;CPU、GPU、內存、硬盤等&#xff09;集中部署于遠程高性能數據中心&#xff0c;通過網絡技術將虛擬桌面實時傳輸到您的任意訪問設備上。 ??如同將高配主機裝入云端&#…

tc 介紹

目錄 1.背景 2. tc介紹 3. tc 丟包 1.背景 需要使用tc 構造丟包場景&#xff0c;注意tc 丟包不能確定丟棄的是否是payload 數據包&#xff0c;有可能丟棄 ack 包。 2. tc介紹 1. 無法正常使用 [rootpool-100-1-1-18 /]# [rootpool-100-1-1-18 /]# tc qdisc add dev swif…

LabVIEW注冊表操作

?本文圍繞LabVIEW中操作Windows 注冊表的 4 個 VI 展開&#xff0c;介紹其功能、使用場景等并對比&#xff0c;助力工程師高效運用注冊表交互功能。各 VI 功能說明&#xff08;一&#xff09;Write the Key功能&#xff1a;創建新注冊表鍵&#xff0c;設置其值&#xff0c;隨后…

阿里云部署若依后,瀏覽器能正常訪問,但是apifox和小程序訪問后報錯鏈接被重置

項目場景&#xff1a;阿里云部署若依后瀏覽器能正常通過https訪問,但是在apifox和小程序調用接口的時候生報錯E問題描述apifox報錯&#xff1a;curl報錯&#xff1a;通過curl可以清楚的看到通過域名是能準確的訪問到IP地址的&#xff0c;說明這個DNS是沒有問題的&#xff0c;但…

升級 Elasticsearch 到新的 AWS Java SDK

作者&#xff1a;來自 Elastic David Turner, Dianna Hohensee Elasticsearch 使用官方的 AWS Java SDK 集成了某些 Amazon Web Services (AWS) 功能。這些集成最早在近 10 年前發布的 Elasticsearch 2.0 版本中引入。 最近&#xff0c;AWS 宣布 Elasticsearch 過去十年使用的…

從0到1學習微服務項目黑馬頭條day01-《APP端登錄功能實現》

個人主頁&#xff1a;VON文章所屬專欄&#xff1a;黑馬頭條個人唯一微信&#xff1a;微信 有一起學習微服務的小伙伴可以加作者微信&#xff1a;單擊即可添加 目錄 一、前言 二、項目概述 1、技術棧 2、項目引入 三、改造項目 1、創建heima-leadnews-user 2、創建實體…

Renesas Electronics RZ/V2N 評估套件

簡介Renesas Electronics RZ/V2N評估套件采用RZ/V2N中檔嵌入式AI微處理器 (MPU) 為嵌入式人工智能 (AI) 應用提供全面的開發平臺。該評估套件包括兩塊板&#xff1a;主板 (RTK0EF0186C02000BJ)&#xff0c;緊湊的153mm x 100mm外形尺寸和RTK0EF0168B00000BJ擴展板。其核心是RZ/…

使用PHP與Apache實現服務器端文件管理

引言 作為前端開發者&#xff0c;你可能經常需要與服務器文件系統交互。本文將詳細介紹如何通過PHP配合Apache實現服務器端文件管理功能。即使你沒有任何PHP經驗&#xff0c;也能按照本教程實現完整解決方案&#xff01; 系統準備 PHP下載與安裝 訪問PHP官網下載頁面 選擇與…