Отправка данных UDP, включая шестнадцатеричный код, с использованием 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>.

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

Ответы Гранта (после отправки пакета с шестнадцатеричным кодом), Хэмиша Смита (использование функции для получения шестнадцатеричных значений) и Хафтора (жестко закодированное сообщение 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.)


person SuperRoach    schedule 04.10.2008    source источник
comment
Хорошо, я возобновил изучение этого. Я обнаружил, что использование wireshark позволяет мне просматривать отправляемые необработанные пакеты udp. Он появляется в примере кода, который я использовал. Символы HEX появляются как пустые (00) символы в фактическом пакете.   -  person SuperRoach    schedule 07.12.2008
comment
Были ли вы когда-либо успешными с этим предприятием? У меня есть один из этих знаков, у которого есть последовательный порт для отправки ему команд, и мне еще не повезло с отправкой ему команд.   -  person NexAddo    schedule 14.03.2012
comment
Да, я решил это некоторое время назад, с уловом - отдельно от всего этого, это управляющая часть кода, которую вам нужно установить. Короче говоря, вам нужно создать файл в оперативной памяти, а не во флэш-памяти для долгосрочной надежности. Эта часть не задокументирована, поэтому мне приходилось время от времени делать это через неуклюжее приложение для Windows. Однако, как только это было сделано, у меня был написан класс на php для обработки отправки (это было сделано через Ethernet).   -  person SuperRoach    schedule 08.06.2012


Ответы (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)
person Hafthor    schedule 04.10.2008

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

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

Public Function HexFromIP(ByVal sIP As String)
    Dim aIP As String()
    Dim sHexCode As String = ""
    aIP = sIP.Split(".")

    For Each IPOct As String In aIP
        sHexCode += Hex(Val(IPOct)).PadLeft(2, "0")
    Next

    Return sHexCode
End Function

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

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

РЕДАКТИРОВАТЬ:

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

person Grant    schedule 04.10.2008

Клиент 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
person Hamish Smith    schedule 04.10.2008
comment
К сожалению, мне пришлось удалить лишние строки вручную, хотя ' распознается и прерывает отображение кода... что неплохо. Я прохожу и пробую ваш подход сейчас. - person SuperRoach; 05.10.2008

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

http://support.favotech.com

person Community    schedule 02.05.2009