当前位置: 首页 > news >正文

Java TCP服务端多线程接收RFID网络读卡器上传数据

本示例使用设备介绍:WIFI/TCP/UDP/HTTP协议RFID液显网络读卡器可二次开发语音播报POE-淘宝网 (taobao.com)

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;public class TCPServer_Java {//监听端口private static final int PORT = 39169;public static void main(String[] args) throws IOException {ServerSocket serverSocket = null;Socket socket = null;try {//建立服务器的Socket,并设定一个监听的端口PORTserverSocket = new ServerSocket(PORT);//由于需要进行循环监听,因此获取消息的操作应放在一个while大循环中while(true){try {//建立跟客户端的连接socket = serverSocket.accept();ServerThread thread = new ServerThread(socket);thread.start();} catch (Exception e) {System.out.println("建立与客户端的连接出现异常");e.printStackTrace();}//ServerThread thread = new ServerThread(socket);//thread.start();}} catch (Exception e) {System.out.println("端口被占用");e.printStackTrace();}finally {serverSocket.close();}}
}//服务端线程类
//继承Thread类的话,必须重写run方法,在run方法中定义需要执行的任务。
class ServerThread extends Thread {private Socket socket ;InputStream inputStream;OutputStream outputStream;public ServerThread(Socket socket){this.socket=socket;}public void run(){try {while (true){//接收客户端的消息,解析信息并回应读卡器//System.out.println(socket);byte[] bytes =new byte[1024];inputStream =socket.getInputStream();int GetDataLen=0;while ((GetDataLen=inputStream.read(bytes))!=-1){       //通过这个方法读取全部数据 及 长度,break;}if(GetDataLen>0) {String bytestr = "";String DataStr = "";String DispStr = "";String CardNo16 = "";String SerialNum = "";long cardno10;long cardnum;for (int p = 0; p < GetDataLen; p++) {bytestr = "00" + Integer.toHexString(bytes[p] & 0xff);DataStr = DataStr + bytestr.substring(bytestr.length() - 2, bytestr.length()) + " ";}System.out.println("Received from " + socket.getRemoteSocketAddress() + " : " + DataStr);switch (bytes[0]) {case (byte)0xc1:case (byte)0xcf:if(bytes[0]==(byte)0xc1){DispStr = "数据解析:接收到读取IC卡号信息,";}else{DispStr = "数据解析:接收到IC卡离开读卡器,";}DispStr = DispStr + "功能码:" + Integer.toHexString(bytes[0] & 0xff);DispStr = DispStr + ",设备IP:" + Integer.toString(bytes[1] & 0xff) + "." + Integer.toString(bytes[2] & 0xff) + "." + Integer.toString(bytes[3] & 0xff) + "." + Integer.toString(bytes[4] & 0xff);DispStr = DispStr + ",机号:" + Integer.toString((bytes[5] & 0xff) + ((bytes[6] & 0xff) * 256));DispStr = DispStr + ",数据包序号:" + Integer.toString((bytes[7] & 0xff) + ((bytes[8] & 0xff) * 256));int Cardlen = bytes[9];DispStr = DispStr + ",卡号长度:" + Integer.toString(Cardlen);CardNo16 = "";for (int p = 10; p < 10 + Cardlen; p++) {bytestr = "00" + Integer.toHexString(bytes[p] & 0xff);CardNo16 = CardNo16 + bytestr.substring(bytestr.length() - 2, bytestr.length());}DispStr = DispStr + ",16进制卡号:" + CardNo16;cardnum = bytes[10] & 0xff;cardnum = cardnum + (bytes[11] & 0xff) * 256;cardnum = cardnum + (bytes[12] & 0xff) * 65536;cardnum = cardnum + (bytes[13] & 0xff) * 16777216;cardno10 = 0;for (int j = 28; j >= 0; j -= 4) {cardno10 = cardno10 << 4 | (cardnum >>> j & 0xF);}DispStr = DispStr + ",转10进制卡号:" + String.format("%010d", cardno10);SerialNum = "";for (int p = 10 + Cardlen; p < GetDataLen; p++) {bytestr = "00" + Integer.toHexString(bytes[p] & 0xff);SerialNum = SerialNum + bytestr.substring(bytestr.length() - 2, bytestr.length());}DispStr = DispStr + ",唯一硬件序号:" + SerialNum;System.out.println(DispStr + "\n");//向客户端发送消息byte[] RespByte=GetResponseData(2); //生成不同的回应数据包outputStream = socket.getOutputStream();outputStream.write(RespByte);bytestr = "";DataStr = "";for (int p = 0; p < RespByte.length; p++) {bytestr = "00" + Integer.toHexString(RespByte[p] & 0xff);DataStr = DataStr + bytestr.substring(bytestr.length() - 2, bytestr.length()) + " ";}System.out.println("Send Data To "+socket.getRemoteSocketAddress()+" : "+DataStr+"\n");break;case (byte)0xd1:case (byte)0xdf:if(bytes[0]==(byte)0xd1){DispStr="数据解析:接收到读取ID卡号信息,";}else{DispStr="数据解析:接收到ID卡离开读卡器,";}DispStr=DispStr+"功能码:"+ Integer.toHexString(bytes[0] & 0xff);DispStr=DispStr+",设备IP:"+  Integer.toString(bytes[1] & 0xff) + "." + Integer.toString(bytes[2] & 0xff) + "." + Integer.toString(bytes[3] & 0xff) + "." + Integer.toString(bytes[4] & 0xff);DispStr=DispStr+",机号:"+  Integer.toString((bytes[5] & 0xff) + ((bytes[6] & 0xff) * 256));DispStr=DispStr+",数据包序号:"+ Integer.toString((bytes[7] & 0xff) + ((bytes[8] & 0xff) * 256));CardNo16="";for (int p = 9; p < 14; p++) {bytestr = "00" + Integer.toHexString(bytes[p] & 0xff);CardNo16 = CardNo16 + bytestr.substring(bytestr.length() - 2, bytestr.length());}DispStr=DispStr+",16进制卡号:"+CardNo16;cardnum = bytes[9] & 0xff;cardnum = cardnum + (bytes[10] & 0xff) * 256;cardnum = cardnum + (bytes[11] & 0xff) * 65536;cardnum = cardnum + (bytes[12] & 0xff) * 16777216;cardno10 = 0;for (int j = 28; j >= 0; j -= 4) {cardno10 = cardno10 << 4 | (cardnum >>> j & 0xF);}DispStr=DispStr+",转10进制卡号:"+ String.format("%010d", cardno10);SerialNum="";for (int p = 14; p < GetDataLen; p++) {bytestr = "00" + Integer.toHexString(bytes[p] & 0xff);SerialNum = SerialNum + bytestr.substring(bytestr.length() - 2, bytestr.length());}DispStr=DispStr+",唯一硬件序号:"+ SerialNum;System.out.println(DispStr+"\n");//向客户端发送消息RespByte=GetResponseData(2); //生成不同的回应数据包outputStream = socket.getOutputStream();outputStream.write(RespByte);bytestr = "";DataStr = "";for (int p = 0; p < RespByte.length; p++) {bytestr = "00" + Integer.toHexString(RespByte[p] & 0xff);DataStr = DataStr + bytestr.substring(bytestr.length() - 2, bytestr.length()) + " ";}System.out.println("Send Data To "+socket.getRemoteSocketAddress()+" : "+DataStr+"\n");break;case (byte)0xf3:DispStr="数据解析:接收到设备心跳包,";DispStr=DispStr+"功能码:"+Integer.toHexString(bytes[0] & 0xff);DispStr=DispStr+",设备IP:"+Integer.toString(bytes[1] & 0xff)+"."+Integer.toString(bytes[2] & 0xff)+"."+Integer.toString(bytes[3] & 0xff)+"."+Integer.toString(bytes[4] & 0xff);DispStr=DispStr+",机器号:"+Integer.toString((bytes[5] & 0xff)+((bytes[6] & 0xff) *256));DispStr=DispStr+",包序号:"+Integer.toString((bytes[7] & 0xff)+((bytes[8] & 0xff) *256));DispStr=DispStr+",心跳码:"+Integer.toHexString(bytes[9] & 0xff);DispStr=DispStr+",长  度:"+Integer.toHexString(bytes[10] & 0xff);DispStr=DispStr+",继电器:"+Integer.toHexString(bytes[11] & 0xff);DispStr=DispStr+",按键值:"+Integer.toHexString(bytes[12] & 0xff);for(int p=13;p<17;p++){bytestr="00"+Integer.toHexString(bytes[p] & 0xff);SerialNum=SerialNum+ bytestr.substring(bytestr.length() -2,bytestr.length());}DispStr=DispStr+",随机码:"+SerialNum;SerialNum="";for(int p=17;p<GetDataLen;p++){bytestr="00"+Integer.toHexString(bytes[p] & 0xff);SerialNum=SerialNum+ bytestr.substring(bytestr.length() -2,bytestr.length());}DispStr=DispStr+",设备序列号:"+SerialNum;System.out.println(DispStr+"\n");break;}}}} catch (Exception e) {System.out.println("客户端主动断开连接了");e.printStackTrace();}//操作结束,关闭sockettry{socket.close();}catch(IOException e){System.out.println("关闭连接出现异常");e.printStackTrace();}}//根据Respcode返回不同的回应数据包static byte[] GetResponseData(int Respcode)  throws Exception {byte[] RespByte= new byte[300];String DispStr="本次刷卡成功,感谢您的使用,再见!                   ";  //满屏显示34个字符,不足后面加空格byte[] DispBuf;switch(Respcode){case 0:            //驱动读卡器蜂鸣响声RespByte[0] = (byte) 0x96;  //蜂鸣响声的指令码RespByte[1] = (byte) 0x00;  //机号低位RespByte[2] = (byte) 0x00;  //机号高,0000表示任意机号RespByte[3] = (byte) 0x01;  //蜂鸣响声代码,取值范围0-12RespByte = Arrays.copyOf(RespByte, 4);break;case 1:            //驱动读卡器显示文字+蜂鸣响声DispBuf= DispStr.getBytes("gb2312"); //显示文字转字节数组RespByte[0]=(byte)0x5a;                          //指令码RespByte[1]=(byte)0x00;                          //机号低RespByte[2]=(byte)0x00;                          //机号高,如果高低位都为0表示任意机号RespByte[3]=(byte)0x02;                          //蜂鸣声代码RespByte[4]=(byte)0x14;                          //显示时长for(int i=0;i<34;i++){                           //显示文字RespByte[i+5]=DispBuf[i];}RespByte = Arrays.copyOf(RespByte, 39);break;case 2:         //驱动读卡器显示文字+蜂鸣响声+继电器开关+TTS语音DispBuf= DispStr.getBytes("gb2312"); //显示文字转字节数组String SpeakStr="";                              //将要播报的TTS语音生成字节数组,最大不能超过126个字节SpeakStr="[v1]";                                //定义语音大小,取值范围v0 到 v16,可加在任何地方SpeakStr=SpeakStr+"欢迎您使用我们的网络读卡器,谢谢!";      //要播报的中文语音byte[] SpeakBuf= SpeakStr.getBytes("gb2312");int    SpeakLen=SpeakBuf.length;                //语音长度int SendLen=11+34+SpeakLen+4;                   //总计发送数据长度RespByte[0]=(byte)0x5C;                          //指令码RespByte[1]=(byte)0x00;                          //机号低RespByte[2]=(byte)0x00;                          //机号高,如果高低位都为0表示任意机号RespByte[3]=(byte)0x01;                          //蜂鸣声代码RespByte[4]=(byte)0xF0;                          //继电器代码 F0表示全部继电器 F1表示1号继电器 F2表示2号继电器RespByte[5]=(byte)0x20;                          //继电器开启时长 低位RespByte[6]=(byte)0x00;                          //继电器开启时长 高位RespByte[7]=(byte)0x14;                          //显示保留时间,单位为秒,为0xFF时表示永久显示RespByte[8]=(byte)0x00;                          //在显示屏中的哪个位置开始RespByte[9]=(byte)0x22;                          //显示字符串长度 为全屏显示为 34 个字符RespByte[10]=(byte)SpeakLen;                     //语音长度for(int i=0;i<34;i++){                           //显示的文字信息RespByte[i+11]=DispBuf[i];}for(int i=0;i<SpeakLen;i++){                     //TTS语音播报信息RespByte[i+45]=SpeakBuf[i];}RespByte[10+34+SpeakLen+1]=(byte)0x55;           //固定的抗干扰后缀RespByte[10+34+SpeakLen+2]=(byte)0xaa;RespByte[10+34+SpeakLen+3]=(byte)0x66;RespByte[10+34+SpeakLen+4]=(byte)0x99;RespByte = Arrays.copyOf(RespByte, 10+34+SpeakLen+5);break;case 3:            //驱动读卡器开启继电器开关RespByte[0]=(byte)0x78;                          //指令码RespByte[1]=(byte)0x00;                          //机号低RespByte[2]=(byte)0x00;                          //机号高,如果高低位都为0表示任意机号RespByte[3]=(byte)0xF0;                          //继电器代码 F0表示全部继电器、F1表示1号继电器 、F2表示2号继电器......RespByte[4]=(byte)0x2C;                          //继电器开启延时低位RespByte[5]=(byte)0x01;                          //继电器开启延时高位,FFFF表示继电器一直开启RespByte = Arrays.copyOf(RespByte, 6);break;default:}return  RespByte;}
}

 

相关文章:

Java TCP服务端多线程接收RFID网络读卡器上传数据

本示例使用设备介绍&#xff1a;WIFI/TCP/UDP/HTTP协议RFID液显网络读卡器可二次开发语音播报POE-淘宝网 (taobao.com) import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; impor…...

SpringCloud——服务网关——GateWay

1.GateWay是什么&#xff1f; gateway也叫服务网关&#xff0c;SpringCloud GateWay使用的是Webflux中的reactor-netty响应式编程组件&#xff0c;底层使用了Netty通讯框架。 gateway的功能有反向代理、鉴权、流量控制、熔断、日志监控...... 2.为什么不使用Zuul&#xff1f…...

Linux程序的地址空间

Linux程序的地址空间 &#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;Linux &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 本博客主要内容深刻理解了什么程序或者进程的地址…...

Docker安装Minio(稳定版)

1、安装 docker pull minio/minio:RELEASE.2021-06-17T00-10-46Z docker run -p 9000:9000 minio/minio:RELEASE.2021-06-17T00-10-46Z server /data 2、访问测试 3、MinIO自定义Access和Secret密钥 要覆盖MinIO的自动生成的密钥&#xff0c;您可以将Access和Secret密钥设为…...

大数据毕业设计选题推荐-超级英雄运营数据监控平台-Hadoop-Spark-Hive

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…...

视频转码教程:轻松制作GIF动态图,一键高效剪辑操作

随着社交媒体的兴起&#xff0c;GIF动态图已经成为了人们表达情感、分享精彩瞬间的重要方式。而将视频转化为GIF动态图&#xff0c;不仅可以方便地在社交媒体上分享&#xff0c;还可以延长视频的播放时长&#xff0c;吸引更多的观众。本篇文章将为大家介绍如何将视频轻松转化为…...

Seata分布式事务实现原理

Seata可以解决分布式事务问题&#xff0c;利用GlobalTransacational(name "fsp-create-order",rollbackFor Exception.class)注解就可以实现全局的事务管理&#xff0c;但是我们需要明白原理的实现。 我们举例创建订单——>调减库存——>调扣余额——>改订…...

Rasa NLU中的组件

Rasa NLU部分主要是解决NER&#xff08;序列建模&#xff09;和意图识别&#xff08;分类建模&#xff09;这2个任务。Rasa NLP是一个基于DAG的通用框架&#xff0c;图中的顶点即组件。组件特征包括有顺序关系、可相互替换、可互斥和可同时使用。有向无环图&#xff08;DAG&…...

redis笔记 三 redis持久化

文章目录 Redis持久化RDB持久化执行时机RDB原理小结 AOF持久化AOF原理AOF配置AOF文件重写 RDB与AOF对比 Redis持久化 redis持久化是为了解决redis宕机时丢失数据的问题&#xff0c;Redis有两种持久化方案&#xff1a; RDB持久化AOF持久化 RDB持久化 RDB全称Redis Database …...

k8s-----数据存储

目录 一、数据存储的概念 二、基本存储 1、EmptyDir存储卷 2、hostPath存储卷 3、nfs共享存储卷 三、高级存储 1、PV&#xff08;持久化卷&#xff09; 2、PVC&#xff08;持久化卷声明&#xff09; 3、静态PV实验 4、动态PV实验 4.1 在stor01节点上安装nfs&#xf…...

macOS电池续航工具:Endurance中文

Endurance for Mac是一款强大而实用的电池管理和优化软件&#xff0c;专为MacBook设计。通过智能调整系统设置和管理后台应用&#xff0c;它能有效延长电池续航时间&#xff0c;提升工作和娱乐效率&#xff0c;成为你在各种场合下的得力助手。 Endurance for Mac软件的功能特色…...

栈(定义,基本操作,顺序存储,链式存储)

目录 1.栈的定义1.重要术语2.特点 2.栈的基本操作3.栈的顺序存储1.顺序栈的定义2.基本操作1.初始化2.进栈3.出栈4.读栈顶 3.共享栈 4.栈的链式存储 1.栈的定义 栈( Stack&#xff09;是只允许在一端进行插入或删除操作的线性表。 一种受限的线性表&#xff0c;只能在栈顶进行插…...

在HTML单页面中,使用Bootstrap框架的多选框如何提交数据

1.引入Bootstrap CSS和JavaScript文件&#xff1a;确保在HTML页面的标签内引入Bootstrap的CSS和JavaScript文件。可以使用CDN链接或者下载本地文件。 <link rel"stylesheet" href"https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css&q…...

当爱好变成职业,会不会就失去了兴趣?

当爱好变成职业&#xff0c;会不会就失去了兴趣&#xff1f; 当兴趣变成职业 1、学习能力变强了&#xff0c;积极主动性增加了。 2、学习努力变现了&#xff0c;赚到的更钱多了。 3、赚钱能力变强了&#xff0c;反过来再次促使兴趣发展&#xff08;兴趣更大了....干劲更足了&…...

3-知识补充-MVC框架

3-知识补充-MVC框架 文章目录 3-知识补充-MVC框架MVC概述M、V、C各自负责功能及常用包MVC框架图非前后端分离框架图前后端分离框架图 MVC概述 MVC&#xff08;Model、View、Controller&#xff09;是软件工程中的一种**软件架构模式&#xff0c;它把软件系统分为模型、视图和控…...

leetcode:141. 环形链表

一、题目 函数原型&#xff1a; bool hasCycle(struct ListNode *head) 二、算法 判断不是环形链表&#xff0c;只需遍历链表找到空结点即可。 判断是环形链表&#xff0c;由于链表是环形的&#xff0c;遍历不会永远不会结束。所以要设置快慢指针&#xff0c;慢指针一次走一步&…...

了解企业邮箱的外观和功能特点

企业邮箱是什么样子的&#xff1f;企业邮箱不是单一产品&#xff0c;而是由一系列电子邮件服务组成的生态系统。这些服务包括但不限于邮件服务器、客户端、安全解决方案等。这些服务共同构成了企业邮箱的基础设施。 在外观上&#xff0c;企业邮箱和个人邮箱没有太大区别。用户通…...

配置阿里云镜像加速器 -docker

1.百度aliyun 2.找到镜像服务ACR 3.搞一个个人版&#xff0c;身份验证一下就行了很简单 4.找到镜像加速器Centos 5.执行下面4条命令&#xff1a;4条命令直接从上面操作文档中粘贴&#xff0c;不容易出错 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<…...

11 抽象向量空间

抽象向量空间 向量是什么函数什么是线性推论向量空间 这是关于3Blue1Brown "线性代数的本质"的学习笔记。 向量是什么 可以是一个箭头&#xff0c;可以是一组实数&#xff0c;即一个坐标对。 箭头在高维&#xff08;4维&#xff0c;甚至更高&#xff09;空间&…...

干洗店洗鞋店管理系统app小程序;

干洗店洗鞋店管理系统是一款专业的洗衣店管理软件&#xff0c;集成了前台收费收银系统、会员卡管理系统和财务报表系统等强大功能。界面简洁优美&#xff0c;操作直观简单。这款系统为干洗店和洗衣店提供了成本分析、利润分析、洗衣流程管理等诸多实用功能&#xff0c;用全新的…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

区块链技术概述

区块链技术是一种去中心化、分布式账本技术&#xff0c;通过密码学、共识机制和智能合约等核心组件&#xff0c;实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点&#xff1a;数据存储在网络中的多个节点&#xff08;计算机&#xff09;&#xff0c;而非…...

spring Security对RBAC及其ABAC的支持使用

RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型&#xff0c;它将权限分配给角色&#xff0c;再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...

智能职业发展系统:AI驱动的职业规划平台技术解析

智能职业发展系统&#xff1a;AI驱动的职业规划平台技术解析 引言&#xff1a;数字时代的职业革命 在当今瞬息万变的就业市场中&#xff0c;传统的职业规划方法已无法满足个人和企业的需求。据统计&#xff0c;全球每年有超过2亿人面临职业转型困境&#xff0c;而企业也因此遭…...

边缘计算网关提升水产养殖尾水处理的远程运维效率

一、项目背景 随着水产养殖行业的快速发展&#xff0c;养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下&#xff0c;而且难以实现精准监控和管理。为了提升尾水处理的效果和效率&#xff0c;同时降低人力成本&#xff0c;某大型水产养殖企业决定…...