作为一种爱好,我对编程一个以太网连接的LED标志以在屏幕上滚动消息很感兴趣。但我在VB.NET中制作UDP发送器时遇到了问题(我目前使用的是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:Client向服务器发送数据包,并从服务器接收数据包):
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(示例中的硬编码chr()消息)在尝试时的答案都不起作用。所以我会研究一下还有什么可能出错。理论上,如果这个字符串成功发送,我应该会收到一条包含"OK"的消息,这将有助于了解它何时工作。
我已经试过了,现在可以监控通过的数据包了。工作数据包示例如下(原始十六进制):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.)
你可以把一个像这样的快速解码器放在一起:
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 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")
。
我也可以给你整个程序的来源,尽管它是为与不同的硬件对话而设计的。
编辑:
你是想用十六进制发送数据包,还是用十六进制获取数据包?
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
他们发布了包括Visual Basic在内的一系列语言的库(在单独的文件中)。我用他们的一个标志测试了演示,它们很有效!
http://support.favotech.com