Отправка данных UDP, включая hex, используя VB.NET

Как хобби, мне интересно программировать светодиодный знак, подключенный к Ethernet, для прокрутки сообщений по экрану. Но у меня проблемы с отправкой отправителя UDP в VB.NET (сейчас я использую 2008).

Теперь знак достаточно хорош, чтобы спецификацию для программирования для него.

Но пример строки для ее отправки (стр. 3):

<0x01>Z30<0x02>AA<0x06><0x1B>0b<0x1C>1<0x1A>1This message will show up on the screen<0x04>

С кодами, такими как < 0x01> , представляющими шестнадцатеричный символ.

Теперь, чтобы отправить это знаку, мне нужно использовать UDP. Тем не менее, в примерах, которые я все кодировал как ASCII перед отправкой, как этот (из UDP: клиент отправляет пакеты и получает пакеты с сервера):

Imports System.Threading
Imports System.Net.Sockets
Imports System.IO
Imports System.Net
Public Class MainClass
 Shared Dim client As UdpClient
 Shared Dim receivePoint As IPEndPoint
 Public Shared Sub Main()
 receivePoint = New IPEndPoint(New IPAddress(0), 0)
 client = New UdpClient(8888)
 Dim thread As Thread = New Thread(New ThreadStart(AddressOf WaitForPackets))
 thread.Start()
 Dim packet As String = "client"
 Console.WriteLine("Sending packet containing: ")
 '
 ' Note the following line below, would appear to be my problem.
 '
 Dim data As Byte() = System.Text.Encoding.ASCII.GetBytes(packet)
 client.Send(data, data.Length, "localhost", 5000)
 Console.WriteLine("Packet sent")
 End Sub
 Shared Public Sub WaitForPackets()
 While True
 Dim data As Byte() = client.Receive(receivePoint)
 Console.WriteLine("Packet received:" & _
 vbCrLf & "Length: " & data.Length & vbCrLf & _
 System.Text.Encoding.ASCII.GetString(data))
 End While
 End Sub ' WaitForPackets
End Class

Чтобы вывести шестнадцатеричный код в VB.NET, я думаю, что синтаксис может быть & H1A - отправить то, что спецификации будут определять как < 0x1A> .

Могу ли я изменить этот код, чтобы правильно отправить правильно сформированный пакет на этот знак?

Ответы от Grant (после отправки пакета с шестнадцатеричным в нем), Hamish Smith (с использованием функции для получения шестнадцатеричных значений) и сообщения Hafthor (hardcoded chr() в пример) при попытке выполнить все не удалось. Поэтому я буду исследовать, что еще может пойти не так. Теоретически, если эта строка отправлена ​​успешно, у меня должно получиться сообщение, содержащее "ОК" назад, что поможет узнать, когда оно работает.

Я попытался и теперь могу отслеживать проходящие пакеты. Пример рабочего пакета - это (в шестнадцатеричном формате): http://www.brettjamesonline.com/misc/forums/other/working.raw против моей версии: http://www.brettjamesonline.com/misc/forums/other/failed.raw. Разница заключается в том, что мои шестнадцатеричные коды все еще не закодированы правильно, как показано в этом бок о бок изображении: http://www.brettjamesonline.com/misc/forums/other/snapshotcoding.png.

Я использовал этот код для создания пакета и отправки его:

container = &H1 & "Z" & &H30 & &H2 & "temp.nrg" & &H1C & "1Something" & &H4
 ' This did not appear to work neither
 'container = Chr(&H1) & "Z" & Chr(&H30) & Chr(&H2) & Chr(&H1C) & "1Something" & Chr(&H4)
 '<0x01>Z00<0x02>FILENAME<0x1C>1Test to display<0x04> <- the "official" spec to send
Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes(container)

(Полный фрагмент: http://pastebin.com/f44417743.)

4 ответа

Вы могли бы собрать быстрый декодер, подобный этому:

Function HexCodeToHexChar(ByVal m as System.Text.RegularExpressions.Match) As String
 Return Chr(Integer.Parse(m.Value.Substring("<0x".Length, 2), _
 Globalization.NumberStyles.HexNumber))
End Function

затем используйте это для преобразования:

Dim r As New System.Text.RegularExpressions.Regex("<0x[0-9a-fA-F]{2}>")
Dim s As String = r.Replace("abc<0x44>efg", AddressOf HexCodeToHexChar)
' s should now be "abcDefg"

вы также можете сделать функцию кодирования, которая отменяет это декодирование (хотя и немного сложнее)

Function HexCharToHexCode(ByVal m As Match) As String
 If m.Value.StartsWith("<0x") And m.Value.EndsWith(">") And m.Value.Length = "<0x??>".Length Then
 Return "<0<0x78>" + m.Value.Substring("<0x".Length)
 ElseIf Asc(m.Value) >= 0 And Asc(m.Value) <= &HFF Then
 Return "<0x" + Right("0" + Hex(Asc(m.Value)), 2) + ">"
 Else
 Throw New ArgumentException("Non-SBCS ANSI characters not supported")
 End If
End Function

и используйте это для преобразования:

Dim r As New Regex("[^ -~]|<0x[0-9a-fA-F]{2}>")
Dim s As String = r.Replace("abc"+chr(4)+"efg", AddressOf HexCharToHexCode)
' s should now be "abc<0x04>efg"

или вы можете просто создать строку со специальными символами в ней, чтобы начать следующим образом:

Dim packet As String = Chr(&H01) + "Z30" + Chr(&H02) + "AA" + Chr(&H06) + _
 Chr(&H1B) + "0b" + Chr(&H1C) + "1" + Chr(&H1A) + _
 "1This message will show up on the screen" + Chr(&H04)

для отправки UDP-пакета должно быть достаточно:

Dim i As New IPEndPoint(IPAddress.Parse("192.168.0.5"), 3001) ''//Target IP:port
Dim u As New UdpClient()
Dim b As Byte() = Encoding.UTF8.GetBytes(s) ''//Where s is the decoded string
u.Send(b, b.Length, i)


Это может помочь. В моей компании мы должны общаться с нашим оборудованием, используя комбинацию ascii и hex.

Я использую эту функцию для прошивки ip-адресов перед отправкой их на аппаратное обеспечение

Public Function HexFromIP(ByVal sIP As String)
 Dim *** As String()
 Dim sHexCode As String = ""
 *** = sIP.Split(".")
 For Each IPOct As String In ***
 sHexCode += Hex(Val(IPOct)).PadLeft(2, "0")
 Next
 Return sHexCode
End Function

И октавно использую hexSomething = Hex(Val(number)).PadLeft(2,"0").

Я могу предоставить вам источник для всей программы, хотя он предназначен для общения с различным оборудованием.

EDIT:

Вы пытаетесь отправить пакеты в шестнадцатеричном формате или получить пакеты в шестнадцатеричном формате?


Они разместили библиотеки для нескольких языков, включая Visual Basic (в отдельном файле). Я протестировал демо с одним из своих знаков, и они работают!

http://support.favotech.com


Клиент UDP отправляет массив байтов. Вы можете использовать поток памяти и записывать байты в массив.

Public Class MainClass
 Shared client As UdpClient
 Shared receivePoint As IPEndPoint
 Public Shared Sub Main()
 receivePoint = New IPEndPoint(New IPAddress(0), 0)
 client = New UdpClient(8888)
 Dim thread As Thread = New Thread(New ThreadStart(AddressOf WaitForPackets))
 thread.Start()
 Dim packet As Packet = New Packet("client")
 Console.WriteLine("Sending packet containing: ")
 Dim data As Byte() = packet.Data
 client.Send(data, data.Length, "localhost", 5000)
 Console.WriteLine("Packet sent")
 End Sub
 Public Shared Sub WaitForPackets()
 While True
 Dim data As Byte() = client.Receive(receivePoint)
 Console.WriteLine("Packet received:" & _
 vbCrLf & "Length: " & data.Length & vbCrLf & _
 System.Text.Encoding.ASCII.GetString(data))
 End While
 End Sub ' WaitForPackets 
End Class 
Public Class Packet 
 Private _message As String 
 Public Sub New(ByVal message As String)
 _message = message
 End Sub
 Public Function Data() As Byte()
 Dim ret(13 + _message.Length) As Byte
 Dim ms As New MemoryStream(ret, True)
 ms.WriteByte(&H1)
 '<0x01>Z30<0x02>AA<0x06><0x1B>0b<0x1C>1<0x1A>1This message will show up on the screen<0x04> 
 ms.Write(System.Text.Encoding.ASCII.GetBytes("Z30"), 0, 3)
 ms.WriteByte(&H2)
 ms.Write(System.Text.Encoding.ASCII.GetBytes("AA"), 0, 2)
 ms.WriteByte(&H6)
 ms.Write(System.Text.Encoding.ASCII.GetBytes("0b"), 0, 2)
 ms.WriteByte(&H1C)
 ms.Write(System.Text.Encoding.ASCII.GetBytes("1"), 0, 1)
 ms.WriteByte(&H1A)
 ms.Write(System.Text.Encoding.ASCII.GetBytes(_message), 0, _message.Length)
 ms.WriteByte(&H4)
 ms.Close()
 Data = ret
 End Function
End Class

licensed under cc by-sa 3.0 with attribution.