Files
Desktop_485BurningTool/Transmitter/DevNetworkCommunication.vb
2025-12-11 10:09:40 +08:00

381 lines
14 KiB
VB.net
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Public Class DevNetworkCommunication
Inherits Transmitter
Public m_Serial As Socket
Public m_SerialComfig As UDPComfig
Public m_Control As Control
'接收数据队列
Public m_ReceiveQueue As List(Of Cmdconfig) = New List(Of Cmdconfig)
'特殊接收处理标志
Public m_SpecialReceiveFlag As Integer
Public recvBufferli As List(Of Byte)
''' <summary>
''' 透传数据包头
''' </summary>
Public _fixedHead As Byte() = {&HAA, &H55}
''' <summary>
''' 透传数据固定ID
''' </summary>
Public _fixeSystemId As Byte() = {&H54, &H33, &H53, &H41}
''' <summary>
''' 透传数据房间信息
''' </summary>
Public _fixeRoomInfo As Byte() = {&HFF, &HFF, &HFF, &HFF}
''' <summary>
''' UDP通讯接收线程
''' </summary>
Private _receiveThread As Thread
Sub New(gControl As Control)
m_SerialComfig = New UDPComfig
m_ReceiveQueue = New List(Of Cmdconfig)
m_ReceiveQueue.Clear()
m_Control = gControl
recvBufferli = New List(Of Byte)
m_SpecialReceiveFlag = -1
CommunicationTypeindex = 2
End Sub
Public Overrides Sub SendData(data As Cmdconfig)
data.CmdSendTime = DateTime.Now
If IsNothing(m_Serial) OrElse Not m_Serial.IsBound Then
RuningLog.OutputLogsToTheControl(m_Control, New RuningLogConfig($"发送器未连接!", Color.Red), 1)
Return
End If
'清空发送缓存
m_Serial.SendTo(data.CmdSendData, m_SerialComfig.TargetEndPoint)
End Sub
Public Overrides Sub CloseTransmitter()
If Not IsNothing(m_Serial) Then
m_Serial.Shutdown(SocketShutdown.Both)
m_Serial.Close()
m_Serial = Nothing
End If
If Not IsNothing(_receiveThread) AndAlso _receiveThread.IsAlive Then
_receiveThread.Abort()
End If
End Sub
Public Overrides Sub ClearSendData()
If IsNothing(m_ReceiveQueue) Then Return
m_ReceiveQueue.Clear()
End Sub
Public Overrides Sub ClearReadData()
End Sub
Public Overrides Function ReceiveData(g_comfig As Cmdconfig) As Cmdconfig
End Function
''' <summary>
''' UDP接收数据
''' </summary>
Private Sub UdpRecviveData()
Dim recvLength As Integer
Dim recvBuffer(1024) As Byte
While m_Serial.IsBound
Try
recvLength = m_Serial.ReceiveFrom(recvBuffer, m_SerialComfig.TargetEndPoint)
'_countRXData += recvLength
Dim buf As Byte() = New Byte(recvLength - 1) {}
Array.Copy(recvBuffer, buf, recvLength)
RuningLog.OutputLogsToTheControl(m_Control, New RuningLogConfig($"RX:{DataProcessing.ByteToString2(buf)}", Color.Blue), 1)
Catch ex As Exception
Console.WriteLine($"Udp Recv Error:{ex.Message}")
Return
End Try
ReceivingDataProcessing(recvBuffer, recvLength)
End While
' If Not IsNothing(m_Transmitter) AndAlso m_Transmitter.IsTransmitter Then m_Transmitter.CloseTransmitter()
End Sub
''' <summary>
''' 接收数据处理
''' </summary>
''' <param name="recvBuffer"></param>
''' <param name="recvLength"></param>
Private Sub ReceivingDataProcessing(recvBuffer() As Byte, recvLength As Integer)
Dim startIndex As Integer '定义一个开始的计数值
Dim packetLength As Integer '定义包的长度
While startIndex < recvLength '判断计数值是否小于总包长
If recvBuffer(startIndex) = _fixedHead(0) AndAlso recvBuffer(startIndex + 1) = _fixedHead(1) Then ' 判断包头是否等于AA55
If recvBuffer(startIndex + 4) = _fixeSystemId(0) AndAlso '判断第4,5,6,7位是否等于固定值
recvBuffer(startIndex + 5) = _fixeSystemId(1) AndAlso
recvBuffer(startIndex + 6) = _fixeSystemId(2) AndAlso
recvBuffer(startIndex + 7) = _fixeSystemId(3) Then
packetLength = recvBuffer(startIndex + 2) + recvBuffer(startIndex + 3) * 256 '赋值包长
If packetLength + startIndex <= recvLength Then '判断包长 + 计数值是否小于等于总包长
Dim packetData(packetLength - 1) As Byte '定义一个新数据包数组
Array.Copy(recvBuffer, startIndex, packetData, 0, packetLength) '复制数组 +5个重载
If CheckCRC16Sucess(packetData, packetData.Length) Then '判断CRC16校验是否通过
'显示数据
DealData(packetData, packetLength) '分部处理数据(显示文字提示)
startIndex += packetData.Length '计数值更新
Else
RuningLog.OutputLogsToTheControl(m_Control, New RuningLogConfig($"CRC16校验失败", Color.Red), 1)
Exit While
End If
Else
RuningLog.OutputLogsToTheControl(m_Control, New RuningLogConfig($"数据包长校验失败!", Color.Red), 1)
Exit While
End If
Else
RuningLog.OutputLogsToTheControl(m_Control, New RuningLogConfig($"数据校验失败!", Color.Red), 1)
Exit While
End If
Else
RuningLog.OutputLogsToTheControl(m_Control, New RuningLogConfig($"非RCU主机发送的数据", Color.Red), 1)
Exit While
End If
End While
End Sub
''' <summary>
''' 检验CRC16成功
''' </summary>
''' <param name="dataBuff"></param>
''' <param name="length"></param>
''' <returns></returns>
Private Function CheckCRC16Sucess(dataBuff() As Byte, length As Integer) As Boolean
Dim crcBytes() As Byte = GetCRC16CheckSum(dataBuff, length - 2)
If crcBytes(0) <> dataBuff(length - 2) OrElse crcBytes(1) <> dataBuff(length - 1) Then Return False
Return True
End Function
''' <summary>
''' 处理数据
''' </summary>
''' <param name="dataBuff"></param>
''' <param name="length"></param>
''' <returns></returns>
Private Function DealData(dataBuff() As Byte, length As Integer) As Boolean
Select Case dataBuff(8)
Case &H70
'获取队列第5个元素
Dim len As Integer = m_ReceiveQueue.Count
Dim item As Cmdconfig
Dim buf(length - 17 - 1) As Byte
Array.Copy(dataBuff, 15, buf, 0, buf.Length)
For i = 0 To len - 1
If (len - 1 - i) < m_ReceiveQueue.Count Then
item = m_ReceiveQueue(len - 1 - i)
If dataBuff(15) = 2 Then
item.OtherProtocol.UDP_TRANSPARENT_MODE_COMMAND_REPLY_STATUS = 1
item.OtherProtocol.UDP_TRANSPARENT_MODE_COMMAND_REPLY_RESULT = dataBuff(16)
End If
If dataBuff(15) = 1 Then
item.OtherProtocol.UDP_QUERY_HOST_CURRENT_MODE_COMMAND_REPLY_STATUS = 1
item.OtherProtocol.UDP_QUERY_HOST_CURRENT_MODE_COMMAND_REPLY_RESULT = dataBuff(16)
End If
'item.Protocol.ParseReceiveData(item, buf)
End If
Next
Case &H71
Dim len As Integer = m_ReceiveQueue.Count
Dim item As Cmdconfig
Dim buf(length - 17 - 1 - 2) As Byte
If 17 + buf.Length < dataBuff.Length Then
Array.Copy(dataBuff, 17, buf, 0, buf.Length)
For i = 0 To len - 1
If (len - 1 - i) < m_ReceiveQueue.Count Then
item = m_ReceiveQueue(len - 1 - i)
'If dataBuff(15) = 2 Then
' item.OtherProtocol.UDP_TRANSPARENT_MODE_COMMAND_REPLY_STATUS = 1
' item.OtherProtocol.UDP_TRANSPARENT_MODE_COMMAND_REPLY_RESULT = dataBuff(16)
'End If
'If dataBuff(15) = 1 Then
' item.OtherProtocol.UDP_QUERY_HOST_CURRENT_MODE_COMMAND_REPLY_STATUS = 1
' item.OtherProtocol.UDP_QUERY_HOST_CURRENT_MODE_COMMAND_REPLY_RESULT = dataBuff(16)
'End If
item.Protocol.ParseReceiveData2(item, buf)
End If
Next
End If
End Select
Return True
End Function
''' <summary>
''' 获取CRC16校验和
''' </summary>
''' <param name="dataBuff">数据</param>
''' <param name="length">数据长度</param>
''' <returns></returns>
Private Function GetCRC16CheckSum(dataBuff() As Byte, length As Integer) As Byte()
Dim crc16 As UInteger
Dim crcBytes() As Byte
crc16 = &HFFFF
For i = 0 To length - 1
crc16 = crc16 And &HFFFF
crc16 = crc16 Xor dataBuff(i)
For bit = 0 To 7
crc16 = IIf((crc16 And 1) = 0, crc16 >> 1, (crc16 >> 1) Xor &HA001)
Next
Next
crc16 = crc16 And &HFFFF
crcBytes = BitConverter.GetBytes(UShort.Parse(crc16))
Return crcBytes
End Function
Public Overrides Function IsTransmitter() As Boolean
If IsNothing(m_Serial) OrElse m_Serial.Connected = False Then Return False
Return True
End Function
Public Overrides Function OpenTransmitter() As Boolean
If Not IsNothing(m_Serial) Then
m_Serial.Shutdown(SocketShutdown.Both)
m_Serial.Close()
End If
If Not IsNothing(_receiveThread) AndAlso _receiveThread.IsAlive Then
_receiveThread.Abort()
End If
m_Serial = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
''加保护机制
m_Serial.Bind(m_SerialComfig.LocalEndPoint)
m_Serial.Connect(m_SerialComfig.TargetEndPoint)
_receiveThread = New Thread(New ThreadStart(AddressOf UdpRecviveData))
_receiveThread.Start()
End Function
Public Overrides Function GetTransmitterStatus() As Boolean
If IsNothing(m_Serial) Then Return False
Return True
End Function
''' <summary>
''' 本地ip/本地端口/目标ip/目标端口
''' </summary>
''' <param name="params"></param>
''' <returns></returns>
Public Overrides Function SetTransmitterParameter(ParamArray params() As Object) As Boolean
If IsNothing(m_SerialComfig) Then Return False
Dim ipAddr As IPAddress
Dim port As Integer
If params.Length > 0 Then
'判断是否为ip
If IPAddress.TryParse(params(0), ipAddr) Then
m_SerialComfig.LocalIP = ipAddr
End If
If params.Length > 1 Then
'判断是否为端口
If Integer.TryParse(params(1), port) Then
m_SerialComfig.LocalPort = port
End If
End If
If params.Length > 2 Then
'判断是否为ip
If IPAddress.TryParse(params(2), ipAddr) Then
m_SerialComfig.TargetIP = ipAddr
End If
If params.Length > 3 Then
'判断是否为端口
If Integer.TryParse(params(3), port) Then
m_SerialComfig.TargetPort = port
End If
End If
End If
End If
'判断本地ip和 端口是否有效
If IsNothing(m_SerialComfig.LocalIP) OrElse IsNothing(m_SerialComfig.LocalPort) Then
MsgBox("本地ip或端口无效")
Else
'判断目标ip和 端口是否有效
m_SerialComfig.LocalEndPoint = New IPEndPoint(m_SerialComfig.LocalIP, m_SerialComfig.LocalPort)
End If
'判断目标ip和 端口是否有效
If IsNothing(m_SerialComfig.TargetIP) OrElse IsNothing(m_SerialComfig.TargetPort) Then
MsgBox("目标ip或端口无效")
Else
m_SerialComfig.TargetEndPoint = New IPEndPoint(m_SerialComfig.TargetIP, m_SerialComfig.TargetPort)
End If
End Function
'判断是否为端口
Private Function IsPort(port As String) As Boolean
Return Integer.TryParse(port, port)
End Function
'判断是否为ip
Private Function IsIP(ip As String) As Boolean
Dim ipAddr As IPAddress
Return IPAddress.TryParse(ip, ipAddr)
End Function
Public Overrides Function SendData(data() As Byte) As Boolean
'data.CmdSendTime = DateTime.Now
If IsNothing(m_Serial) Then
RuningLog.OutputLogsToTheControl(m_Control, New RuningLogConfig($"发送器未连接!", Color.Red), 1)
Return False
End If
'清空发送缓存
m_Serial.SendTo(data, m_SerialComfig.TargetEndPoint)
Return True
End Function
End Class
Public Class UDPComfig
'本地ip
Public LocalIP As IPAddress
'本地端口
Public LocalPort As Integer
'目标ip
Public TargetIP As IPAddress
'目标端口
Public TargetPort As Integer
'发送网络端点
Public LocalEndPoint As IPEndPoint
'接收网络端点
Public TargetEndPoint As IPEndPoint
'获取 串口名称列表
Sub New()
LocalIP = GetLocalIP.Item(0)
End Sub
'获取本地IP列表
Public Shared Function GetLocalIP() As List(Of IPAddress)
Dim address() As IPAddress
Dim destAddress As New List(Of IPAddress)
address = Dns.GetHostEntry(Dns.GetHostName()).AddressList
For Each pAddress As IPAddress In address
If pAddress.AddressFamily = AddressFamily.InterNetwork Then
destAddress.Add(pAddress)
End If
Next
Return destAddress
End Function
End Class