VB.net TCP服务端监听端口接收客户端RFID网络读卡器上传的读卡数据

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

Imports System.Threading
Imports System.Net
Imports System.Net.Sockets
Public Class Form1Dim ListenSocket As SocketDim Dict As New Dictionary(Of String, Socket) '用于保存连接的客户的套接字的键值对集合Dim DictThre As New Dictionary(Of String, Thread) '用于保存通信线程的键值对集合Dim LocalIp As StringDim SendBuff() As BytePublic Sub getIp()     '获取本机所有网卡的IPDim Address() As System.Net.IPAddressDim i As IntegerAddress = Dns.GetHostByName(Dns.GetHostName()).AddressListIf UBound(Address) < 0 ThenMsgBox("未能查找到本台电脑安装的网卡,暂不能启动本软件。", MsgBoxStyle.Critical + vbOKOnly, "注意")EndElseFor i = 0 To UBound(Address)comboBox4.Items.Add(Address(i).ToString())NextcomboBox4.SelectedIndex = 0LocalIp = comboBox4.Text.Trim()End IfEnd SubPrivate Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.LoadgetIp()comboBox4.SelectedIndex = 0End SubPrivate Sub btn_conn_Click(sender As Object, e As EventArgs) Handles btn_conn.ClickIf btn_conn.Text = "开启TCP服务,允许新客户端接入" ThenTextBox.CheckForIllegalCrossThreadCalls = False             '取消文本框的跨线程检查Dim localAddress As IPAddress = IPAddress.Parse(comboBox4.Text.Trim())Dim EndPoint As New IPEndPoint(localAddress, txb_port.Text) '创建一个网络节点对象ListenSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)ListenSocket.Bind(EndPoint)                                 '给负责监听的套接字绑定一个网络节点ListenSocket.Listen(100)                                    '侦听,最多接受100个连接Dim thre = New Thread(AddressOf Connect)                    '创建一个新的线程用于处理客户端发来的连接请求thre.IsBackground = True                                    '设为后台线程thre.Start()                                                '开启线程           btn_conn.Text = "停止新客户端连接"listBox2.Items.Add("TCP端口监听服务已开启,新客户端设备可以连接并上传数据......")listBox2.Items.Add("")listBox2.SelectedIndex = listBox2.Items.Count - 1Else            ListenSocket.Close()ListenSocket = Nothingbtn_conn.Text = "开启TCP服务,允许新客户端接入"listBox2.Items.Add("TCP服务端已禁止新客户端连接,已连接的客户端设备可继续上传数据......")listBox2.Items.Add("")listBox2.SelectedIndex = listBox2.Items.Count - 1End IfEnd SubSub Connect() '处理客户端的连接请求的过程While TrueTryDim SockConect As Socket = listenSocket.AcceptDict.Add(SockConect.RemoteEndPoint.ToString, SockConect)    '将连接成功的套接字添加到键值对集合listBox1.Items.Add(SockConect.RemoteEndPoint.ToString)      '添加到列表Dim Thre As New Thread(AddressOf RecClient)                 '创建一个新的线程用于和链接成功的套接字通信Thre.IsBackground = True                                    '设为后台线程Thre.Start(SockConect)DictThre.Add(SockConect.RemoteEndPoint.ToString, Thre)      '将创建的通信线程添加到键值对集合CatchEnd TryEnd WhileEnd SubSub RecClient(ByVal SockTelNet As Socket) '处理客户端发来的数据While TrueTryDim getdata(1024) As ByteDim RecLen As Int32Dim HexStr As StringTry '捕获异常RecLen = SockTelNet.Receive(getdata) '接受客户端发来得信息Catch ss As SocketExceptionlistBox2.Items.Add(ss.NativeErrorCode & vbCrLf & ss.Message) '显示错误信息Dict.Remove(SockTelNet.RemoteEndPoint.ToString) '移除断开连接的套接字                    ReturnCatch s As ExceptionlistBox2.Items.Add(s.Message)ReturnEnd TryIf RecLen > 0 ThenDim StrMsg As StringStrMsg = DateTime.Now.ToLongTimeString() + "  Get From " + SockTelNet.RemoteEndPoint.ToString + " : "For i = 0 To RecLen - 1StrMsg = StrMsg + getdata(i).ToString("X2") + " "NextIf listBox2.Items.Count() > 100 Then listBox2.Items.Clear()listBox2.Items.Add(StrMsg)Select Case getdata(0)Case &HC1, &HCFIf getdata(0) = &HC1 ThenStrMsg = "数据解析:IC读卡器上传卡号,"ElseStrMsg = "数据解析:IC卡离开读卡器,"End IfStrMsg = StrMsg + "IP[" + getdata(1).ToString("D") + "." + getdata(2).ToString("D") + "." + getdata(3).ToString("D") + "." + getdata(4).ToString("D") + "],"StrMsg = StrMsg + "机号[" + (getdata(5) + getdata(6) * 256).ToString("D") + "],"StrMsg = StrMsg + "数据包号[" + (getdata(7) + getdata(8) * 256).ToString("D") + "],"StrMsg = StrMsg + "卡号长度[" + getdata(9).ToString("D") + "],"HexStr = ""For i = 10 To 10 + getdata(9) - 1HexStr = HexStr + getdata(i).ToString("X2")NextStrMsg = StrMsg + "16进制卡号[" + HexStr + "],"HexStr = ""For i = 10 + getdata(9) To RecLen - 1HexStr = HexStr + getdata(i).ToString("X2")NextStrMsg = StrMsg + "唯一硬件序号[" + HexStr + "]"listBox2.Items.Add(StrMsg)listBox2.Items.Add("")listBox2.SelectedIndex = listBox2.Items.Count - 1If CheckBox1.Checked ThenGetRespData()SockTelNet.Send(SendBuff)StrMsg = DateTime.Now.ToLongTimeString() + "  Send To  " + SockTelNet.RemoteEndPoint.ToString + " : "For i = 0 To SendBuff.Length - 1StrMsg = StrMsg + SendBuff(i).ToString("X2") + " "NextlistBox2.Items.Add(StrMsg)listBox2.Items.Add("")listBox2.SelectedIndex = listBox2.Items.Count - 1End IfCase &HD1, &HDFIf getdata(0) = &HD1 ThenStrMsg = "数据解析:ID读卡器上传卡号,"ElseStrMsg = "数据解析:ID卡离开读卡器,"End IfStrMsg = StrMsg + "IP[" + getdata(1).ToString("D") + "." + getdata(2).ToString("D") + "." + getdata(3).ToString("D") + "." + getdata(4).ToString("D") + "],"StrMsg = StrMsg + "机号[" + (getdata(5) + getdata(6) * 256).ToString("D") + "],"StrMsg = StrMsg + "数据包号[" + (getdata(7) + getdata(8) * 256).ToString("D") + "],"StrMsg = StrMsg + "16进制卡号[" + getdata(9).ToString("X2") + getdata(10).ToString("X2") + getdata(11).ToString("X2") + getdata(12).ToString("X2") + getdata(13).ToString("X2") + "],"HexStr = ""For i = 14 To RecLen - 1HexStr = HexStr + getdata(i).ToString("X2")NextStrMsg = StrMsg + "唯一硬件序号[" + HexStr + "]"listBox2.Items.Add(StrMsg)listBox2.Items.Add("")listBox2.SelectedIndex = listBox2.Items.Count - 1Case &HF3StrMsg = "数据解析:读卡器心跳数据包,"StrMsg = StrMsg + "IP[" + getdata(1).ToString("D") + "." + getdata(2).ToString("D") + "." + getdata(3).ToString("D") + "." + getdata(4).ToString("D") + "],"StrMsg = StrMsg + "机号[" + (getdata(5) + getdata(6) * 256).ToString("D") + "],"StrMsg = StrMsg + "数据包号[" + (getdata(7) + getdata(8) * 256).ToString("D") + "],"StrMsg = StrMsg + "心跳类型[" + getdata(9).ToString("X2") + "],"StrMsg = StrMsg + "长度[" + getdata(10).ToString("D") + "],"StrMsg = StrMsg + "继电器状态[" + getdata(11).ToString("X2") + "],"StrMsg = StrMsg + "外部输入状态[" + getdata(12).ToString("X2") + "],"StrMsg = StrMsg + "随机动态码[" + getdata(13).ToString("X2") + getdata(14).ToString("X2") + getdata(15).ToString("X2") + getdata(17).ToString("X2") + "],"HexStr = ""For i = 17 To RecLen - 1HexStr = HexStr + getdata(i).ToString("X2")NextStrMsg = StrMsg + "唯一硬件序号[" + HexStr + "]"listBox2.Items.Add(StrMsg)listBox2.Items.Add("")listBox2.SelectedIndex = listBox2.Items.Count - 1End SelectEnd IfCatchEnd TryEnd WhileEnd Sub'选择在线设备向其发送指令Sub ButtoSend(ByVal sendcode As Integer)Dim seleid As StringDim dispstr As StringDim i As IntegerIf listBox1.SelectedIndex >= 0 Thenseleid = listBox1.TextGetSenddata(sendcode)Dict.Item(seleid).Send(SendBuff)dispstr = DateTime.Now.ToLongTimeString() + "  Send To  " + seleid + " : "For i = 0 To SendBuff.Length - 1dispstr = dispstr + SendBuff(i).ToString("X2") + " "NextlistBox2.Items.Add(dispstr)listBox2.Items.Add("")listBox2.SelectedIndex = listBox2.Items.Count - 1ElseMsgBox("请先在客户端列表中选择要发送指令的在线客户端!", MsgBoxStyle.Information + MsgBoxStyle.OkOnly, "提示")End IfEnd Sub'按回应需要生成发送缓冲数据Sub GetRespData()If RadioButton3.Checked ThenGetSenddata(0)ElseIf RadioButton4.Checked ThenGetSenddata(1)ElseIf RadioButton5.Checked ThenGetSenddata(2)ElseGetSenddata(3)End IfEnd Sub'按发送需要生成发送缓冲数据Sub GetSenddata(ByVal sendcode As Integer)Dim i As LongDim strs As StringDim textbyte() As ByteSelect Case sendcodeCase 0ReDim SendBuff(38)SendBuff(0) = &H5A      '驱动显示文字+蜂鸣响声的功能码SendBuff(1) = 0         '机号低位SendBuff(2) = 0         '机号高位,高低位为0表示任意机号If checkBox2.Checked Then   '蜂鸣响声SendBuff(3) = comboBox3.SelectedIndex   '蜂鸣响声代码If radioButton2.Checked Then        '背光灯状态不变SendBuff(3) = SendBuff(3) Or 128End IfElseSendBuff(3) = &HFF              '不响蜂鸣声If radioButton2.Checked Then    '背光灯状态不变SendBuff(3) = SendBuff(3) And 127End IfEnd IfSendBuff(4) = dispdelay.Valuestrs = textBox12.Text + "                                   "textbyte = System.Text.Encoding.GetEncoding(936).GetBytes(strs)For i = 0 To 33SendBuff(5 + i) = textbyte(i)NextCase 1strs = "[v" + SYDX.Value.ToString() + "]"    '设置语音大小,在需要发送的语音字符串中任何位置加入[v10],表示将音量调到10级(范围0~16,0表示静音,16最大,每次重开机后,音量重置为10级)!strs = strs + textBox1.Text.Trim()textbyte = System.Text.Encoding.GetEncoding(936).GetBytes(strs)Dim displen As IntegerDim voiclen As IntegerDim commlen As Integerdisplen = 34voiclen = textbyte.Lengthcommlen = 10 + displen + voiclen + 4ReDim SendBuff(commlen)SendBuff(0) = &H5C      '驱动显示文字+蜂鸣响声的功能码+开继电器+播报TTS语音SendBuff(1) = 0         '机号低位SendBuff(2) = 0         '机号高位,高低位为0表示任意机号If checkBox2.Checked Then   '蜂鸣响声SendBuff(3) = comboBox3.SelectedIndex   '蜂鸣响声代码If radioButton2.Checked Then        '背光灯状态不变SendBuff(3) = SendBuff(3) Or 128End IfElseSendBuff(3) = &HFF              '不响蜂鸣声If radioButton2.Checked Then    '背光灯状态不变SendBuff(3) = SendBuff(3) And 127End IfEnd IfSelect Case comboBox2.SelectedIndex '根据选择开启对应的继电器Case 1SendBuff(4) = &HF1Case 2SendBuff(4) = &HF2Case 3SendBuff(4) = &HF3Case 4SendBuff(4) = &HF4Case 5SendBuff(4) = &HF5Case 6SendBuff(4) = &HF6Case 7SendBuff(4) = &HF7Case 8SendBuff(4) = &HF8Case ElseSendBuff(4) = &HF0End Selecti = CLng(textBox11.Text)    '继电器开启时长SendBuff(5) = i Mod 256SendBuff(6) = Int(i / 256) Mod 256SendBuff(7) = dispdelay.Value  '显示时长SendBuff(8) = 0                '显示起始位SendBuff(9) = displen          '显示长度SendBuff(10) = voiclen         'TTS语音长度strs = textBox12.Text + "                                   "Dim dispbyte() As Bytedispbyte = System.Text.Encoding.GetEncoding(936).GetBytes(strs)For i = 0 To displen - 1        '显示文字SendBuff(11 + i) = dispbyte(i)NextFor i = 0 To voiclen - 1        'TTS语音SendBuff(11 + displen + i) = textbyte(i)NextSendBuff(11 + displen + voiclen + 0) = &H55     '防干扰后缀SendBuff(11 + displen + voiclen + 1) = &HAASendBuff(11 + displen + voiclen + 2) = &H66SendBuff(11 + displen + voiclen + 3) = &H99Case 2ReDim SendBuff(3)SendBuff(0) = &H96      '驱动蜂鸣响声的功能码SendBuff(1) = 0         '机号低位SendBuff(2) = 0         '机号高位,高低位为0表示任意机号SendBuff(3) = comboBox3.SelectedIndexCase 3ReDim SendBuff(5)SendBuff(0) = &H78      '驱动开关继电器的功能码SendBuff(1) = 0         '机号低位SendBuff(2) = 0         '机号高位,高低位为0表示任意机号Select Case comboBox2.SelectedIndex '根据选择开启对应的继电器Case 1SendBuff(3) = &HF1Case 2SendBuff(3) = &HF2Case 3SendBuff(3) = &HF3Case 4SendBuff(3) = &HF4Case 5SendBuff(3) = &HF5Case 6SendBuff(3) = &HF6Case 7SendBuff(3) = &HF7Case 8SendBuff(3) = &HF8Case ElseSendBuff(3) = &HF0End Selecti = CLng(textBox11.Text)    '开启时长SendBuff(4) = i Mod 256SendBuff(5) = Int(i / 256) Mod 256Case 4ReDim SendBuff(5)SendBuff(0) = &H78      '驱动开关继电器的功能码SendBuff(1) = 0         '机号低位SendBuff(2) = 0         '机号高位,高低位为0表示任意机号Select Case comboBox2.SelectedIndex '根据选择关闭对应的继电器Case 1SendBuff(3) = &HE1Case 2SendBuff(3) = &HE2Case 3SendBuff(3) = &HE3Case 4SendBuff(3) = &HE4Case 5SendBuff(3) = &HE5Case 6SendBuff(3) = &HE6Case 7SendBuff(3) = &HE7Case 8SendBuff(3) = &HE8Case ElseSendBuff(3) = &HE0End Selecti = CLng(textBox11.Text)    '开启时长SendBuff(4) = i Mod 256SendBuff(5) = Int(i / 256) Mod 256End SelectEnd SubPrivate Sub button6_Click(sender As Object, e As EventArgs) Handles button6.ClickButtoSend(2)End SubPrivate Sub button7_Click(sender As Object, e As EventArgs) Handles button7.ClickButtoSend(3)End SubPrivate Sub button8_Click(sender As Object, e As EventArgs) Handles button8.ClickButtoSend(4)End SubPrivate Sub button10_Click(sender As Object, e As EventArgs) Handles button10.ClickButtoSend(0)End SubPrivate Sub button9_Click(sender As Object, e As EventArgs) Handles button9.ClickButtoSend(1)End SubPrivate Sub button3_Click(sender As Object, e As EventArgs) Handles button3.ClickDim copstr As StringDim I As LongClipboard.Clear()copstr = ""For I = 0 To listBox2.Items.Count - 1copstr = copstr & listBox2.Items(I)copstr = copstr & vbCrLfNextClipboard.SetText(copstr)MsgBox("TCP通讯日志报文已拷贝!", MsgBoxStyle.Information + MsgBoxStyle.OkOnly, "提示")End SubPrivate Sub button2_Click(sender As Object, e As EventArgs) Handles button2.ClicklistBox2.Items.Clear()End Sub
End Class

 

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

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

相关文章

【汇编】汇编语言的介绍

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、汇编是什么&#xff1f;二、为什么要学习汇编语言&#xff1f;三、学习汇编语言的好处四、安装汇编环境4.1 下载虚拟环境4.2 配置虚拟环境 总结 前言 计算…

使用百度语音识别技术实现文字转语音的Java应用

探讨如何使用百度语音识别技术将文字转换为语音的Java应用。百度语音识别技术是一种强大的语音识别服务&#xff0c;可以将输入的文字转换为自然流畅的语音输出。我们将使用Java编程语言来实现这个应用&#xff0c;并提供相应的源代码。 首先&#xff0c;我们需要准备一些前提…

Cesium深入浅出之自定义材质

引子 做为一名技术宅却没有能拿得出手的技术无疑是最可悲的事情。三年前&#xff0c;当我第一次接触Cesium的时候就被它强大和炫丽所折服&#xff0c;最关键的是它还是开源的。以前我一直是机械地敲着业务代码&#xff0c;好像计算机程序就只能干这点事情一样&#xff0c;而 C…

Qt文档阅读笔记-Fetch More Example解析

Fetch More Example这个例子说明了如何在视图模型上添加记录。 这个例子由一个对话框组成&#xff0c;在Directory的输入框中&#xff0c;可输入路径信息。应用程序会载入路径信息的文件信息等。不需要按回车键就能搜索。 当有大量数据时&#xff0c;需要对视图模型进行批量增…

Git忽略文件.gitignore的使用

1.为什么使用? 当你使用git add .的时候有没有遇到把你不想提交的文件也添加到了缓存中去&#xff1f;比如项目的本地配置信息&#xff0c;如果你上传到Git中去其他人pull下来的时候就会和他本地的配置有冲突&#xff0c;所以这样的个性化配置文件我们一般不把它推送到git服务…

数据库 并发控制

多用户数据库系统&#xff1a;允许多个用户同时使用同一个数据库的数据库系统 交叉并发方式&#xff1a;在单处理机系统中&#xff0c;事务的并行执行实际上是这些并行事务的并行操作轮流交叉运行 同时并发方式&#xff1a;在多处理机系统中&#xff0c;每个处理机可以运行一个…

Java设计模式-结构型模式-代理模式

代理模式 代理模式静态代理动态代理JDK动态代理CGlib动态代理 代理模式 创建一个代理对象来控制对原始对象的访问&#xff0c;可以用来扩展原始对象的功能&#xff0c;同时保护原始对象 一般使用代理模式的目的有两个&#xff1a; 保护目标对象增强目标对象 代理模式有两种实现…

【OpenCV实现图像:用OpenCV图像处理技巧之巧用直方图】

文章目录 概要前置条件统计数据分析直方图均衡化原理小结 概要 图像处理是计算机视觉领域中的重要组成部分&#xff0c;而直方图在图像处理中扮演着关键的角色。如何巧妙地运用OpenCV库中的图像处理技巧&#xff0c;特别是直方图相关的方法&#xff0c;来提高图像质量、改善细…

stm32超声波测距不准的解决方法(STM32 delay_us()产生1us)及stm32智能小车超声波测距代码(C语言版本)

首先要说明一下原理&#xff1a;使用stm32无法准确产生1us的时间&#xff0c;但是超声波测距一定要依赖时间&#xff0c;时间不准&#xff0c;距离一定不准&#xff0c;这是要肯定的&#xff0c;但是在不准确的情况下&#xff0c;要测量一个比较准确的时间&#xff0c;那么只能…

同一个Unity项目打开两个Unity Editor实例

特殊情况下&#xff0c;同一个项目需要同时打开两个编辑器做测试&#xff0c;如多人在线游戏&#xff0c;或者有通信功能的时候就有这样的需求。同时也为了方便调试和观察日志。并且修改的是同一份代码。 命令介绍&#xff1a; 实现思路&#xff1a; 使用 mklink 命令 分别创建…

使用 huggingface_hub 镜像下载 大模型

download.py &#x1f447; import os # 配置 hf镜像 os.environ[HF_ENDPOINT] https://hf-mirror.com# 设置保存的路径 local_dir "XXXXXX"# 设置仓库id model_id "sensenova/piccolo-large-zh"cmd f"huggingface-cli download --resume-downlo…

【MySQL】库的相关操作 + 库的备份和还原

库的操作 前言正式开始创建数据库删除数据库编码集查看系统默认字符集以及校验规则字符集校验规则 所有支持的字符集和校验规则所有字符集所有校验规则 指明字符集和校验规则创建数据库相同的字符集用不同的校验规则读取会出现什么情况 alter修改数据库show create databasealt…

瑞萨e2studio(29)----SPI速率解析

瑞萨e2studio.29--SPI速率解析 概述视频教学时钟配置解析RA4M2的BRR值时钟速率7.5M下寄存器值3K下寄存器值 概述 在嵌入式系统的设计中&#xff0c;串行外设接口&#xff08;SPI&#xff09;的通信速率是一个关键参数&#xff0c;它直接影响到系统的性能和稳定性。瑞萨电子的…

C# Onnx LSTR 基于Transformer的端到端实时车道线检测

目录 效果 模型信息 项目 代码 下载 效果 模型信息 lstr_360x640.onnx Inputs ------------------------- name&#xff1a;input_rgb tensor&#xff1a;Float[1, 3, 360, 640] name&#xff1a;input_mask tensor&#xff1a;Float[1, 1, 360, 640] -----------------…

适配器模式 rust和java的实现

文章目录 适配器模式介绍何时使用应用实例优点缺点使用场景 实现java实现rust 实现 rust代码仓库 适配器模式 适配器模式&#xff08;Adapter Pattern&#xff09;是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式&#xff0c;它结合了两个独立接口的功能…

【每日一题】区域和检索 - 数组可修改

文章目录 Tag题目来源解题思路方法一&#xff1a;分块方法二&#xff1a;线段树方法三&#xff1a;树状数组 写在最后 Tag 【树状数组】【线段树】【分块】【前缀和】【设计类】【2023-11-13】 题目来源 307. 区域和检索 - 数组可修改 解题思路 使用前缀和解决不行吗&#x…

centos利用find提权反弹shell

需要说明的是利用find命令进行提权的方式已经不存在了&#xff0c;因为Linux默认不会为find命令授予suid权限&#xff0c;这里只是刻意的制造出了一种存在提权的环境 首先我们先介绍一下find命令&#xff0c;find命令主要用来在Linux中查找文件使用&#xff0c;它可以进行最基础…

Brute Force

Brute Force "Brute Force"&#xff08;暴力破解&#xff09;指的是一种通过尝试所有可能的组合来获取访问、解密或破解信息的攻击方法。这种攻击方法通常是基于暴力和不断尝试的&#xff0c;不依赖漏洞或弱点。通常用于破解密码、破坏系统或获取未经授权的访问权限…

数据分析实战 | 逻辑回归——病例自动诊断分析

目录 一、数据及分析对象 二、目的及分析任务 三、方法及工具 四、数据读入 五、数据理解 六、数据准备 七、模型训练 八、模型评价 九、模型调参 十、模型预测 一、数据及分析对象 CSV文件——“bc_data.csv” 数据集链接&#xff1a;https://download.csdn.net/d…

MongoDB基础知识~

引入MongoDB&#xff1a; 在面对高并发&#xff0c;高效率存储和访问&#xff0c;高扩展性和高可用性等的需求下&#xff0c;我们之前所学习过的关系型数据库(MySql,sql server…)显得有点力不从心&#xff0c;而这些需求在我们的生活中也是随处可见的&#xff0c;例如在社交中…