本 示例使用设备介绍: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