249 lines
6.7 KiB
VB.net
249 lines
6.7 KiB
VB.net
|
|
'Imports System.Net
|
|||
|
|
'Imports System.Net.Sockets
|
|||
|
|
|
|||
|
|
'Public Class WebService
|
|||
|
|
' Implements IDisposable
|
|||
|
|
|
|||
|
|
' Enum PacketDataEnum
|
|||
|
|
' Head
|
|||
|
|
' SerialNumber
|
|||
|
|
' ParamLength
|
|||
|
|
' CheckValue
|
|||
|
|
' Command
|
|||
|
|
' Param
|
|||
|
|
' End Enum
|
|||
|
|
|
|||
|
|
' <Flags()>
|
|||
|
|
' Enum PacketSendCmdEnum
|
|||
|
|
' Heartbeat = &H1
|
|||
|
|
|
|||
|
|
' End Enum
|
|||
|
|
|
|||
|
|
' <Flags()>
|
|||
|
|
' Enum PacketReceiveCmdEnum
|
|||
|
|
' Heartbeat = &HA1
|
|||
|
|
|
|||
|
|
' End Enum
|
|||
|
|
|
|||
|
|
' Private _localPublicIp As String
|
|||
|
|
|
|||
|
|
' Private ReadOnly _udpClient As UdpClient
|
|||
|
|
|
|||
|
|
' Private _sendPacketSn As Integer
|
|||
|
|
|
|||
|
|
' Private ReadOnly _hostName As String
|
|||
|
|
|
|||
|
|
' Private ReadOnly _remotePort As Integer
|
|||
|
|
|
|||
|
|
' Private _online As Boolean
|
|||
|
|
|
|||
|
|
' Private _failCount As Integer
|
|||
|
|
|
|||
|
|
' Sub New(hostName As String, port As Integer)
|
|||
|
|
' _hostName = hostName
|
|||
|
|
' _remotePort = port
|
|||
|
|
|
|||
|
|
' _udpClient = New UdpClient()
|
|||
|
|
' _sendPacketSn = 0
|
|||
|
|
|
|||
|
|
' RetryCount = 2
|
|||
|
|
' RetryInterval = 5
|
|||
|
|
' WaitRelayTimeout = 2000
|
|||
|
|
|
|||
|
|
' _online = False
|
|||
|
|
' _localPublicIp = String.Empty
|
|||
|
|
' End Sub
|
|||
|
|
|
|||
|
|
|
|||
|
|
' Public ReadOnly Property LocalPublicIp() As String
|
|||
|
|
' Get
|
|||
|
|
' Return _localPublicIp
|
|||
|
|
' End Get
|
|||
|
|
' End Property
|
|||
|
|
|
|||
|
|
|
|||
|
|
' Public ReadOnly Property Online() As Boolean
|
|||
|
|
' Get
|
|||
|
|
' Return _online
|
|||
|
|
' End Get
|
|||
|
|
' End Property
|
|||
|
|
|
|||
|
|
' ''' <summary>
|
|||
|
|
' ''' 重试次数,不包含第一次发送次数,默认值2
|
|||
|
|
' ''' </summary>
|
|||
|
|
' ''' <returns></returns>
|
|||
|
|
' Public Property RetryCount() As Integer
|
|||
|
|
|
|||
|
|
' ''' <summary>
|
|||
|
|
' ''' 重试间隔,单位ms,默认5ms
|
|||
|
|
' ''' </summary>
|
|||
|
|
' ''' <returns></returns>
|
|||
|
|
' Public Property RetryInterval() As Integer
|
|||
|
|
|
|||
|
|
' ''' <summary>
|
|||
|
|
' ''' 等待接收超时时间,单位ms,默认2000ms
|
|||
|
|
' ''' </summary>
|
|||
|
|
' ''' <returns></returns>
|
|||
|
|
' Public Property WaitRelayTimeout() As Integer
|
|||
|
|
|
|||
|
|
|
|||
|
|
' Public Sub SendHeartbeatPacket(serviceIndex As Integer)
|
|||
|
|
' Dim sendByte() As Byte = FillPacket(CByte(PacketSendCmdEnum.Heartbeat), BitConverter.GetBytes(serviceIndex))
|
|||
|
|
|
|||
|
|
' Send(sendByte)
|
|||
|
|
' End Sub
|
|||
|
|
|
|||
|
|
|
|||
|
|
' Public Function FillPacket(cmd As Byte, param() As Byte) As Byte()
|
|||
|
|
' Dim result(PacketDataEnum.Command + param.Length) As Byte
|
|||
|
|
' result(PacketDataEnum.Head) = &HAA
|
|||
|
|
' result(PacketDataEnum.SerialNumber) = CByte(_sendPacketSn)
|
|||
|
|
' result(PacketDataEnum.ParamLength) = CByte(param.Length)
|
|||
|
|
' result(PacketDataEnum.CheckValue) = &H0
|
|||
|
|
' result(PacketDataEnum.Command) = cmd
|
|||
|
|
|
|||
|
|
' Array.Copy(param, 0, result, PacketDataEnum.Param, param.Length)
|
|||
|
|
' result(PacketDataEnum.CheckValue) = GetCheckSum(result)
|
|||
|
|
|
|||
|
|
' Return result
|
|||
|
|
' End Function
|
|||
|
|
|
|||
|
|
|
|||
|
|
' Public Sub Send(packet() As Byte)
|
|||
|
|
' Static receivedReply As Boolean = False
|
|||
|
|
' Static waitReplyStartTime As DateTime
|
|||
|
|
|
|||
|
|
' receivedReply = False
|
|||
|
|
' For i As Integer = 0 To RetryCount
|
|||
|
|
' _udpClient.Send(packet, packet.Length, _hostName, _remotePort)
|
|||
|
|
' waitReplyStartTime = Now
|
|||
|
|
|
|||
|
|
|
|||
|
|
' While receivedReply = False AndAlso (Now - waitReplyStartTime).TotalMilliseconds < WaitRelayTimeout
|
|||
|
|
' If _udpClient.Available <= 0 Then
|
|||
|
|
' Threading.Thread.Sleep(50)
|
|||
|
|
' Continue While
|
|||
|
|
' End If
|
|||
|
|
|
|||
|
|
' Dim ep As IPEndPoint = Nothing
|
|||
|
|
' Dim receiveByte() As Byte = _udpClient.Receive(ep)
|
|||
|
|
|
|||
|
|
' '校验
|
|||
|
|
' Try
|
|||
|
|
' CheckPacket(receiveByte)
|
|||
|
|
' Catch ex As Exception
|
|||
|
|
' ApplicationLog.WriteErrorLog($"Check Receive Data Error:{ex.Message}")
|
|||
|
|
' Continue While
|
|||
|
|
' End Try
|
|||
|
|
|
|||
|
|
|
|||
|
|
' '处理
|
|||
|
|
' Try
|
|||
|
|
' DealPacket(receiveByte)
|
|||
|
|
' Catch ex As Exception
|
|||
|
|
' ApplicationLog.WriteErrorLog($"Deal Receive Data Error:{ex.Message}")
|
|||
|
|
' Continue While
|
|||
|
|
' End Try
|
|||
|
|
|
|||
|
|
' receivedReply = True
|
|||
|
|
' End While
|
|||
|
|
|
|||
|
|
' If receivedReply Then
|
|||
|
|
' Exit For
|
|||
|
|
' End If
|
|||
|
|
|
|||
|
|
' Threading.Thread.Sleep(RetryInterval)
|
|||
|
|
' Next
|
|||
|
|
|
|||
|
|
' If _sendPacketSn + 1 >= 256 Then
|
|||
|
|
' _sendPacketSn = 0
|
|||
|
|
' Else
|
|||
|
|
' _sendPacketSn += 1
|
|||
|
|
' End If
|
|||
|
|
|
|||
|
|
' If receivedReply = False Then
|
|||
|
|
' _failCount += 1
|
|||
|
|
' If _failCount >= 3 Then
|
|||
|
|
' _failCount = 3
|
|||
|
|
' _online = False
|
|||
|
|
' End If
|
|||
|
|
' Else
|
|||
|
|
' _failCount = 0
|
|||
|
|
' _online = True
|
|||
|
|
' End If
|
|||
|
|
' End Sub
|
|||
|
|
|
|||
|
|
|
|||
|
|
' Private Sub CheckPacket(packet() As Byte)
|
|||
|
|
' If packet(PacketDataEnum.Head) <> &HAA Then
|
|||
|
|
' Throw New Exception($"Invalid Packet Head!Src:{packet(PacketDataEnum.Head)} Dest:{&HAA}")
|
|||
|
|
' End If
|
|||
|
|
|
|||
|
|
' If packet(PacketDataEnum.SerialNumber) <> _sendPacketSn Then
|
|||
|
|
' Throw New Exception($"Invalid Packet Sn!Src: {packet(PacketDataEnum.SerialNumber)} Dest:{_sendPacketSn}")
|
|||
|
|
' End If
|
|||
|
|
|
|||
|
|
' Dim destLength As Integer = packet.Length - PacketDataEnum.Param
|
|||
|
|
' If packet(PacketDataEnum.ParamLength) <> destLength Then
|
|||
|
|
' Throw New Exception($"Invalid Packet Lengnt!Src:{packet(PacketDataEnum.ParamLength)} Dest:{destLength}")
|
|||
|
|
' End If
|
|||
|
|
|
|||
|
|
' If GetBytesSum(packet) <> &HFF Then
|
|||
|
|
' Throw New Exception($"Invalid Packet CheckValue!Src:{BitConverter.ToString(packet)}")
|
|||
|
|
' End If
|
|||
|
|
|
|||
|
|
' End Sub
|
|||
|
|
|
|||
|
|
|
|||
|
|
' Private Function GetCheckSum(packet() As Byte) As Byte
|
|||
|
|
' Dim result As Integer
|
|||
|
|
|
|||
|
|
' For Each b As Byte In packet
|
|||
|
|
' result += b
|
|||
|
|
' result = result And &HFF
|
|||
|
|
' Next
|
|||
|
|
|
|||
|
|
' Return CByte(&HFF - result)
|
|||
|
|
' End Function
|
|||
|
|
|
|||
|
|
|
|||
|
|
' Private Function GetBytesSum(packet() As Byte) As Byte
|
|||
|
|
' Dim result As Integer
|
|||
|
|
|
|||
|
|
' For Each b As Byte In packet
|
|||
|
|
' result += b
|
|||
|
|
' result = result And &HFF
|
|||
|
|
' Next
|
|||
|
|
|
|||
|
|
' Return CByte(result)
|
|||
|
|
' End Function
|
|||
|
|
|
|||
|
|
|
|||
|
|
' Public Sub DealPacket(packet() As Byte)
|
|||
|
|
' Select Case packet(PacketDataEnum.Command)
|
|||
|
|
' Case CByte(PacketReceiveCmdEnum.Heartbeat)
|
|||
|
|
' DealHeartbeatPacket(packet)
|
|||
|
|
' Case Else
|
|||
|
|
' Throw New Exception($"Unknown Command:{packet(PacketDataEnum.Command)}")
|
|||
|
|
' End Select
|
|||
|
|
|
|||
|
|
' End Sub
|
|||
|
|
|
|||
|
|
|
|||
|
|
' Private Sub DealHeartbeatPacket(packet() As Byte)
|
|||
|
|
' Dim tmpIp As String
|
|||
|
|
' tmpIp = $"{packet(PacketDataEnum.Param)}.{packet(PacketDataEnum.Param + 1)}.{packet(PacketDataEnum.Param + 2)}.{packet(PacketDataEnum.Param + 3)}"
|
|||
|
|
|
|||
|
|
' If String.Compare(LocalPublicIp,tmpIp) <> 0 Then
|
|||
|
|
' _localPublicIp = tmpIp
|
|||
|
|
' End If
|
|||
|
|
|
|||
|
|
' End Sub
|
|||
|
|
|
|||
|
|
' Public Sub Dispose() Implements IDisposable.Dispose
|
|||
|
|
' _udpClient.Dispose()
|
|||
|
|
|
|||
|
|
' End Sub
|
|||
|
|
|
|||
|
|
'End Class
|